Tobias Pfeiffer edited this page Mar 1, 2014 · 13 revisions

If you were directed to this page by a JRuby warning, it's probably because you're using JRuby 1.7 in combination with Java objects you've turned into singletons or to which you've added instance variables.

JRuby 1.7 deprecates using instance variables or singletons on Java objects without first calling __persistent__ = true on the object's Java class. JRuby 1.7 and JRuby 9k will both attempt to make Java objects persistent after the first use of instance vars or singletons, but in 9k we will warn for each case. We recommend using other mechanisms to store per-Java-object data, and you may want to pass -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all such patterns in your code before JRuby 9k.

See the warning at the bottom of this page for known issues with singletons and instance variables on Java objects.

To set a Java class to be persistent, use code similar to the following:

java_importjava.util.ArrayListlist=ArrayList.new# These lines will warn if ArrayList is not set persistent yetclass << list;endlist.instance_variable_set(:@foo,'bar')ArrayList.__persistent__=true# no warning for these lines, but all ArrayList will now have cached proxiesclass << list;endlist.instance_variable_set(:@foo,'bar')

This does not cascade down-hierarchy; it must be done for each individual Java class whose instances you expect to use instance vars or singletons with.

For more information, read on.

Java Object Proxy Caching

In order to pass Java objects through Ruby call paths in JRuby, we wrap them in a thin wrapper called the "proxy" or "Java object proxy". These wrappers hold the original Java object and allow it to behave like a Ruby object throughout the system.

In JRuby versions 1.6.x and lower, we also cached these proxies in an attempt to ensure the same object would get the same proxy every time it entered Ruby. This was primarily done to support user-defined instance variables or singleton objects on arbitrary Java objects, since it is not possible to actually modify the structure of the Java object.

However, this caching incurred a heavy cost. Each Java object entering Ruby caused the creation of a weak reference and structural elements in an internal map called the ObjectProxyCache. This greatly increased the overhead of receiving objects from Java calls, and potentially hindered efficient garbage collection due to all those weakrefs.

Deprecating Proxy Caching

As of JRuby 9k, the proxy cache will become opt-in on a per-class basis. If you intend to set instance variables or create singletons from Java objects, you'll need to call JavaClassNameHere.__persistent__ = true on the Java class in Ruby code. This will specify that all that class's objects should have their proxies cached.

We will also attempt to turn on this flag lazily, but with a warning. Because objects may enter Ruby through multiple paths before you set an instance variable or make a singleton, we can't guarantee all existing proxies will reflect those lazily-made changes. We recommend setting __persistent__ = true on classes before receiving or constructing instances of them.

See the example above for example usage of __persistent__ = true.

JRuby 1.7 will still cache all proxies by default, but will issue a one-time warning if you're using instance variables or singletons on Java objects. We recommend passing -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all uses of instance vars or singletons on Java objects in your code.

Alternatives

The simplest alternative would be to store this attached state in a separate structure, like a Hash (properly mutexed) somewhere in the current JRuby environment. This will allow you to localize the caching perf hit to just those objects where you need it.

You may also wish to reference objects weakly, as we did in ObjectProxyCache. The weakling gem provides a solid, consistent weak-reference implementation as well as a WeakHash implementation.

Warning

Whether you set __persistent__ or not, you must keep a reference to the Ruby wrapper object alive in order for it to stay in memory. The caching mechanism JRuby uses allows for either the original Java object or the proxy to be garbage collected if they are no longer referenced, so that the proxy caching does not cause objects to stay alive past their normal lifespan.

Put another way: If you are adding instance variables to or making a singleton object of a Java object, the Ruby object wrapper must stay alive to persist your modifications.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Tobias Pfeiffer edited this page Mar 1, 2014 · 13 revisions

If you were directed to this page by a JRuby warning, it's probably because you're using JRuby 1.7 in combination with Java objects you've turned into singletons or to which you've added instance variables.

JRuby 1.7 deprecates using instance variables or singletons on Java objects without first calling __persistent__ = true on the object's Java class. JRuby 1.7 and JRuby 9k will both attempt to make Java objects persistent after the first use of instance vars or singletons, but in 9k we will warn for each case. We recommend using other mechanisms to store per-Java-object data, and you may want to pass -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all such patterns in your code before JRuby 9k.

See the warning at the bottom of this page for known issues with singletons and instance variables on Java objects.

To set a Java class to be persistent, use code similar to the following:

java_importjava.util.ArrayListlist=ArrayList.new# These lines will warn if ArrayList is not set persistent yetclass << list;endlist.instance_variable_set(:@foo,'bar')ArrayList.__persistent__=true# no warning for these lines, but all ArrayList will now have cached proxiesclass << list;endlist.instance_variable_set(:@foo,'bar')

This does not cascade down-hierarchy; it must be done for each individual Java class whose instances you expect to use instance vars or singletons with.

For more information, read on.

Java Object Proxy Caching

In order to pass Java objects through Ruby call paths in JRuby, we wrap them in a thin wrapper called the "proxy" or "Java object proxy". These wrappers hold the original Java object and allow it to behave like a Ruby object throughout the system.

In JRuby versions 1.6.x and lower, we also cached these proxies in an attempt to ensure the same object would get the same proxy every time it entered Ruby. This was primarily done to support user-defined instance variables or singleton objects on arbitrary Java objects, since it is not possible to actually modify the structure of the Java object.

However, this caching incurred a heavy cost. Each Java object entering Ruby caused the creation of a weak reference and structural elements in an internal map called the ObjectProxyCache. This greatly increased the overhead of receiving objects from Java calls, and potentially hindered efficient garbage collection due to all those weakrefs.

Deprecating Proxy Caching

As of JRuby 9k, the proxy cache will become opt-in on a per-class basis. If you intend to set instance variables or create singletons from Java objects, you'll need to call JavaClassNameHere.__persistent__ = true on the Java class in Ruby code. This will specify that all that class's objects should have their proxies cached.

We will also attempt to turn on this flag lazily, but with a warning. Because objects may enter Ruby through multiple paths before you set an instance variable or make a singleton, we can't guarantee all existing proxies will reflect those lazily-made changes. We recommend setting __persistent__ = true on classes before receiving or constructing instances of them.

See the example above for example usage of __persistent__ = true.

JRuby 1.7 will still cache all proxies by default, but will issue a one-time warning if you're using instance variables or singletons on Java objects. We recommend passing -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all uses of instance vars or singletons on Java objects in your code.

Alternatives

The simplest alternative would be to store this attached state in a separate structure, like a Hash (properly mutexed) somewhere in the current JRuby environment. This will allow you to localize the caching perf hit to just those objects where you need it.

You may also wish to reference objects weakly, as we did in ObjectProxyCache. The weakling gem provides a solid, consistent weak-reference implementation as well as a WeakHash implementation.

Warning

Whether you set __persistent__ or not, you must keep a reference to the Ruby wrapper object alive in order for it to stay in memory. The caching mechanism JRuby uses allows for either the original Java object or the proxy to be garbage collected if they are no longer referenced, so that the proxy caching does not cause objects to stay alive past their normal lifespan.

Put another way: If you are adding instance variables to or making a singleton object of a Java object, the Ruby object wrapper must stay alive to persist your modifications.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Tobias Pfeiffer edited this page Mar 1, 2014 · 13 revisions

If you were directed to this page by a JRuby warning, it's probably because you're using JRuby 1.7 in combination with Java objects you've turned into singletons or to which you've added instance variables.

JRuby 1.7 deprecates using instance variables or singletons on Java objects without first calling __persistent__ = true on the object's Java class. JRuby 1.7 and JRuby 9k will both attempt to make Java objects persistent after the first use of instance vars or singletons, but in 9k we will warn for each case. We recommend using other mechanisms to store per-Java-object data, and you may want to pass -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all such patterns in your code before JRuby 9k.

See the warning at the bottom of this page for known issues with singletons and instance variables on Java objects.

To set a Java class to be persistent, use code similar to the following:

java_importjava.util.ArrayListlist=ArrayList.new# These lines will warn if ArrayList is not set persistent yetclass << list;endlist.instance_variable_set(:@foo,'bar')ArrayList.__persistent__=true# no warning for these lines, but all ArrayList will now have cached proxiesclass << list;endlist.instance_variable_set(:@foo,'bar')

This does not cascade down-hierarchy; it must be done for each individual Java class whose instances you expect to use instance vars or singletons with.

For more information, read on.

Java Object Proxy Caching

In order to pass Java objects through Ruby call paths in JRuby, we wrap them in a thin wrapper called the "proxy" or "Java object proxy". These wrappers hold the original Java object and allow it to behave like a Ruby object throughout the system.

In JRuby versions 1.6.x and lower, we also cached these proxies in an attempt to ensure the same object would get the same proxy every time it entered Ruby. This was primarily done to support user-defined instance variables or singleton objects on arbitrary Java objects, since it is not possible to actually modify the structure of the Java object.

However, this caching incurred a heavy cost. Each Java object entering Ruby caused the creation of a weak reference and structural elements in an internal map called the ObjectProxyCache. This greatly increased the overhead of receiving objects from Java calls, and potentially hindered efficient garbage collection due to all those weakrefs.

Deprecating Proxy Caching

As of JRuby 9k, the proxy cache will become opt-in on a per-class basis. If you intend to set instance variables or create singletons from Java objects, you'll need to call JavaClassNameHere.__persistent__ = true on the Java class in Ruby code. This will specify that all that class's objects should have their proxies cached.

We will also attempt to turn on this flag lazily, but with a warning. Because objects may enter Ruby through multiple paths before you set an instance variable or make a singleton, we can't guarantee all existing proxies will reflect those lazily-made changes. We recommend setting __persistent__ = true on classes before receiving or constructing instances of them.

See the example above for example usage of __persistent__ = true.

JRuby 1.7 will still cache all proxies by default, but will issue a one-time warning if you're using instance variables or singletons on Java objects. We recommend passing -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all uses of instance vars or singletons on Java objects in your code.

Alternatives

The simplest alternative would be to store this attached state in a separate structure, like a Hash (properly mutexed) somewhere in the current JRuby environment. This will allow you to localize the caching perf hit to just those objects where you need it.

You may also wish to reference objects weakly, as we did in ObjectProxyCache. The weakling gem provides a solid, consistent weak-reference implementation as well as a WeakHash implementation.

Warning

Whether you set __persistent__ or not, you must keep a reference to the Ruby wrapper object alive in order for it to stay in memory. The caching mechanism JRuby uses allows for either the original Java object or the proxy to be garbage collected if they are no longer referenced, so that the proxy caching does not cause objects to stay alive past their normal lifespan.

Put another way: If you are adding instance variables to or making a singleton object of a Java object, the Ruby object wrapper must stay alive to persist your modifications.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Tobias Pfeiffer edited this page Mar 1, 2014 · 13 revisions

If you were directed to this page by a JRuby warning, it's probably because you're using JRuby 1.7 in combination with Java objects you've turned into singletons or to which you've added instance variables.

JRuby 1.7 deprecates using instance variables or singletons on Java objects without first calling __persistent__ = true on the object's Java class. JRuby 1.7 and JRuby 9k will both attempt to make Java objects persistent after the first use of instance vars or singletons, but in 9k we will warn for each case. We recommend using other mechanisms to store per-Java-object data, and you may want to pass -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all such patterns in your code before JRuby 9k.

See the warning at the bottom of this page for known issues with singletons and instance variables on Java objects.

To set a Java class to be persistent, use code similar to the following:

java_importjava.util.ArrayListlist=ArrayList.new# These lines will warn if ArrayList is not set persistent yetclass << list;endlist.instance_variable_set(:@foo,'bar')ArrayList.__persistent__=true# no warning for these lines, but all ArrayList will now have cached proxiesclass << list;endlist.instance_variable_set(:@foo,'bar')

This does not cascade down-hierarchy; it must be done for each individual Java class whose instances you expect to use instance vars or singletons with.

For more information, read on.

Java Object Proxy Caching

In order to pass Java objects through Ruby call paths in JRuby, we wrap them in a thin wrapper called the "proxy" or "Java object proxy". These wrappers hold the original Java object and allow it to behave like a Ruby object throughout the system.

In JRuby versions 1.6.x and lower, we also cached these proxies in an attempt to ensure the same object would get the same proxy every time it entered Ruby. This was primarily done to support user-defined instance variables or singleton objects on arbitrary Java objects, since it is not possible to actually modify the structure of the Java object.

However, this caching incurred a heavy cost. Each Java object entering Ruby caused the creation of a weak reference and structural elements in an internal map called the ObjectProxyCache. This greatly increased the overhead of receiving objects from Java calls, and potentially hindered efficient garbage collection due to all those weakrefs.

Deprecating Proxy Caching

As of JRuby 9k, the proxy cache will become opt-in on a per-class basis. If you intend to set instance variables or create singletons from Java objects, you'll need to call JavaClassNameHere.__persistent__ = true on the Java class in Ruby code. This will specify that all that class's objects should have their proxies cached.

We will also attempt to turn on this flag lazily, but with a warning. Because objects may enter Ruby through multiple paths before you set an instance variable or make a singleton, we can't guarantee all existing proxies will reflect those lazily-made changes. We recommend setting __persistent__ = true on classes before receiving or constructing instances of them.

See the example above for example usage of __persistent__ = true.

JRuby 1.7 will still cache all proxies by default, but will issue a one-time warning if you're using instance variables or singletons on Java objects. We recommend passing -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all uses of instance vars or singletons on Java objects in your code.

Alternatives

The simplest alternative would be to store this attached state in a separate structure, like a Hash (properly mutexed) somewhere in the current JRuby environment. This will allow you to localize the caching perf hit to just those objects where you need it.

You may also wish to reference objects weakly, as we did in ObjectProxyCache. The weakling gem provides a solid, consistent weak-reference implementation as well as a WeakHash implementation.

Warning

Whether you set __persistent__ or not, you must keep a reference to the Ruby wrapper object alive in order for it to stay in memory. The caching mechanism JRuby uses allows for either the original Java object or the proxy to be garbage collected if they are no longer referenced, so that the proxy caching does not cause objects to stay alive past their normal lifespan.

Put another way: If you are adding instance variables to or making a singleton object of a Java object, the Ruby object wrapper must stay alive to persist your modifications.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Tobias Pfeiffer edited this page Mar 1, 2014 · 13 revisions

If you were directed to this page by a JRuby warning, it's probably because you're using JRuby 1.7 in combination with Java objects you've turned into singletons or to which you've added instance variables.

JRuby 1.7 deprecates using instance variables or singletons on Java objects without first calling __persistent__ = true on the object's Java class. JRuby 1.7 and JRuby 9k will both attempt to make Java objects persistent after the first use of instance vars or singletons, but in 9k we will warn for each case. We recommend using other mechanisms to store per-Java-object data, and you may want to pass -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all such patterns in your code before JRuby 9k.

See the warning at the bottom of this page for known issues with singletons and instance variables on Java objects.

To set a Java class to be persistent, use code similar to the following:

java_importjava.util.ArrayListlist=ArrayList.new# These lines will warn if ArrayList is not set persistent yetclass << list;endlist.instance_variable_set(:@foo,'bar')ArrayList.__persistent__=true# no warning for these lines, but all ArrayList will now have cached proxiesclass << list;endlist.instance_variable_set(:@foo,'bar')

This does not cascade down-hierarchy; it must be done for each individual Java class whose instances you expect to use instance vars or singletons with.

For more information, read on.

Java Object Proxy Caching

In order to pass Java objects through Ruby call paths in JRuby, we wrap them in a thin wrapper called the "proxy" or "Java object proxy". These wrappers hold the original Java object and allow it to behave like a Ruby object throughout the system.

In JRuby versions 1.6.x and lower, we also cached these proxies in an attempt to ensure the same object would get the same proxy every time it entered Ruby. This was primarily done to support user-defined instance variables or singleton objects on arbitrary Java objects, since it is not possible to actually modify the structure of the Java object.

However, this caching incurred a heavy cost. Each Java object entering Ruby caused the creation of a weak reference and structural elements in an internal map called the ObjectProxyCache. This greatly increased the overhead of receiving objects from Java calls, and potentially hindered efficient garbage collection due to all those weakrefs.

Deprecating Proxy Caching

As of JRuby 9k, the proxy cache will become opt-in on a per-class basis. If you intend to set instance variables or create singletons from Java objects, you'll need to call JavaClassNameHere.__persistent__ = true on the Java class in Ruby code. This will specify that all that class's objects should have their proxies cached.

We will also attempt to turn on this flag lazily, but with a warning. Because objects may enter Ruby through multiple paths before you set an instance variable or make a singleton, we can't guarantee all existing proxies will reflect those lazily-made changes. We recommend setting __persistent__ = true on classes before receiving or constructing instances of them.

See the example above for example usage of __persistent__ = true.

JRuby 1.7 will still cache all proxies by default, but will issue a one-time warning if you're using instance variables or singletons on Java objects. We recommend passing -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all uses of instance vars or singletons on Java objects in your code.

Alternatives

The simplest alternative would be to store this attached state in a separate structure, like a Hash (properly mutexed) somewhere in the current JRuby environment. This will allow you to localize the caching perf hit to just those objects where you need it.

You may also wish to reference objects weakly, as we did in ObjectProxyCache. The weakling gem provides a solid, consistent weak-reference implementation as well as a WeakHash implementation.

Warning

Whether you set __persistent__ or not, you must keep a reference to the Ruby wrapper object alive in order for it to stay in memory. The caching mechanism JRuby uses allows for either the original Java object or the proxy to be garbage collected if they are no longer referenced, so that the proxy caching does not cause objects to stay alive past their normal lifespan.

Put another way: If you are adding instance variables to or making a singleton object of a Java object, the Ruby object wrapper must stay alive to persist your modifications.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Tobias Pfeiffer edited this page Mar 1, 2014 · 13 revisions

If you were directed to this page by a JRuby warning, it's probably because you're using JRuby 1.7 in combination with Java objects you've turned into singletons or to which you've added instance variables.

JRuby 1.7 deprecates using instance variables or singletons on Java objects without first calling __persistent__ = true on the object's Java class. JRuby 1.7 and JRuby 9k will both attempt to make Java objects persistent after the first use of instance vars or singletons, but in 9k we will warn for each case. We recommend using other mechanisms to store per-Java-object data, and you may want to pass -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all such patterns in your code before JRuby 9k.

See the warning at the bottom of this page for known issues with singletons and instance variables on Java objects.

To set a Java class to be persistent, use code similar to the following:

java_importjava.util.ArrayListlist=ArrayList.new# These lines will warn if ArrayList is not set persistent yetclass << list;endlist.instance_variable_set(:@foo,'bar')ArrayList.__persistent__=true# no warning for these lines, but all ArrayList will now have cached proxiesclass << list;endlist.instance_variable_set(:@foo,'bar')

This does not cascade down-hierarchy; it must be done for each individual Java class whose instances you expect to use instance vars or singletons with.

For more information, read on.

Java Object Proxy Caching

In order to pass Java objects through Ruby call paths in JRuby, we wrap them in a thin wrapper called the "proxy" or "Java object proxy". These wrappers hold the original Java object and allow it to behave like a Ruby object throughout the system.

In JRuby versions 1.6.x and lower, we also cached these proxies in an attempt to ensure the same object would get the same proxy every time it entered Ruby. This was primarily done to support user-defined instance variables or singleton objects on arbitrary Java objects, since it is not possible to actually modify the structure of the Java object.

However, this caching incurred a heavy cost. Each Java object entering Ruby caused the creation of a weak reference and structural elements in an internal map called the ObjectProxyCache. This greatly increased the overhead of receiving objects from Java calls, and potentially hindered efficient garbage collection due to all those weakrefs.

Deprecating Proxy Caching

As of JRuby 9k, the proxy cache will become opt-in on a per-class basis. If you intend to set instance variables or create singletons from Java objects, you'll need to call JavaClassNameHere.__persistent__ = true on the Java class in Ruby code. This will specify that all that class's objects should have their proxies cached.

We will also attempt to turn on this flag lazily, but with a warning. Because objects may enter Ruby through multiple paths before you set an instance variable or make a singleton, we can't guarantee all existing proxies will reflect those lazily-made changes. We recommend setting __persistent__ = true on classes before receiving or constructing instances of them.

See the example above for example usage of __persistent__ = true.

JRuby 1.7 will still cache all proxies by default, but will issue a one-time warning if you're using instance variables or singletons on Java objects. We recommend passing -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all uses of instance vars or singletons on Java objects in your code.

Alternatives

The simplest alternative would be to store this attached state in a separate structure, like a Hash (properly mutexed) somewhere in the current JRuby environment. This will allow you to localize the caching perf hit to just those objects where you need it.

You may also wish to reference objects weakly, as we did in ObjectProxyCache. The weakling gem provides a solid, consistent weak-reference implementation as well as a WeakHash implementation.

Warning

Whether you set __persistent__ or not, you must keep a reference to the Ruby wrapper object alive in order for it to stay in memory. The caching mechanism JRuby uses allows for either the original Java object or the proxy to be garbage collected if they are no longer referenced, so that the proxy caching does not cause objects to stay alive past their normal lifespan.

Put another way: If you are adding instance variables to or making a singleton object of a Java object, the Ruby object wrapper must stay alive to persist your modifications.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Tobias Pfeiffer edited this page Mar 1, 2014 · 13 revisions

If you were directed to this page by a JRuby warning, it's probably because you're using JRuby 1.7 in combination with Java objects you've turned into singletons or to which you've added instance variables.

JRuby 1.7 deprecates using instance variables or singletons on Java objects without first calling __persistent__ = true on the object's Java class. JRuby 1.7 and JRuby 9k will both attempt to make Java objects persistent after the first use of instance vars or singletons, but in 9k we will warn for each case. We recommend using other mechanisms to store per-Java-object data, and you may want to pass -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all such patterns in your code before JRuby 9k.

See the warning at the bottom of this page for known issues with singletons and instance variables on Java objects.

To set a Java class to be persistent, use code similar to the following:

java_importjava.util.ArrayListlist=ArrayList.new# These lines will warn if ArrayList is not set persistent yetclass << list;endlist.instance_variable_set(:@foo,'bar')ArrayList.__persistent__=true# no warning for these lines, but all ArrayList will now have cached proxiesclass << list;endlist.instance_variable_set(:@foo,'bar')

This does not cascade down-hierarchy; it must be done for each individual Java class whose instances you expect to use instance vars or singletons with.

For more information, read on.

Java Object Proxy Caching

In order to pass Java objects through Ruby call paths in JRuby, we wrap them in a thin wrapper called the "proxy" or "Java object proxy". These wrappers hold the original Java object and allow it to behave like a Ruby object throughout the system.

In JRuby versions 1.6.x and lower, we also cached these proxies in an attempt to ensure the same object would get the same proxy every time it entered Ruby. This was primarily done to support user-defined instance variables or singleton objects on arbitrary Java objects, since it is not possible to actually modify the structure of the Java object.

However, this caching incurred a heavy cost. Each Java object entering Ruby caused the creation of a weak reference and structural elements in an internal map called the ObjectProxyCache. This greatly increased the overhead of receiving objects from Java calls, and potentially hindered efficient garbage collection due to all those weakrefs.

Deprecating Proxy Caching

As of JRuby 9k, the proxy cache will become opt-in on a per-class basis. If you intend to set instance variables or create singletons from Java objects, you'll need to call JavaClassNameHere.__persistent__ = true on the Java class in Ruby code. This will specify that all that class's objects should have their proxies cached.

We will also attempt to turn on this flag lazily, but with a warning. Because objects may enter Ruby through multiple paths before you set an instance variable or make a singleton, we can't guarantee all existing proxies will reflect those lazily-made changes. We recommend setting __persistent__ = true on classes before receiving or constructing instances of them.

See the example above for example usage of __persistent__ = true.

JRuby 1.7 will still cache all proxies by default, but will issue a one-time warning if you're using instance variables or singletons on Java objects. We recommend passing -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all uses of instance vars or singletons on Java objects in your code.

Alternatives

The simplest alternative would be to store this attached state in a separate structure, like a Hash (properly mutexed) somewhere in the current JRuby environment. This will allow you to localize the caching perf hit to just those objects where you need it.

You may also wish to reference objects weakly, as we did in ObjectProxyCache. The weakling gem provides a solid, consistent weak-reference implementation as well as a WeakHash implementation.

Warning

Whether you set __persistent__ or not, you must keep a reference to the Ruby wrapper object alive in order for it to stay in memory. The caching mechanism JRuby uses allows for either the original Java object or the proxy to be garbage collected if they are no longer referenced, so that the proxy caching does not cause objects to stay alive past their normal lifespan.

Put another way: If you are adding instance variables to or making a singleton object of a Java object, the Ruby object wrapper must stay alive to persist your modifications.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Tobias Pfeiffer edited this page Mar 1, 2014 · 13 revisions

If you were directed to this page by a JRuby warning, it's probably because you're using JRuby 1.7 in combination with Java objects you've turned into singletons or to which you've added instance variables.

JRuby 1.7 deprecates using instance variables or singletons on Java objects without first calling __persistent__ = true on the object's Java class. JRuby 1.7 and JRuby 9k will both attempt to make Java objects persistent after the first use of instance vars or singletons, but in 9k we will warn for each case. We recommend using other mechanisms to store per-Java-object data, and you may want to pass -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all such patterns in your code before JRuby 9k.

See the warning at the bottom of this page for known issues with singletons and instance variables on Java objects.

To set a Java class to be persistent, use code similar to the following:

java_importjava.util.ArrayListlist=ArrayList.new# These lines will warn if ArrayList is not set persistent yetclass << list;endlist.instance_variable_set(:@foo,'bar')ArrayList.__persistent__=true# no warning for these lines, but all ArrayList will now have cached proxiesclass << list;endlist.instance_variable_set(:@foo,'bar')

This does not cascade down-hierarchy; it must be done for each individual Java class whose instances you expect to use instance vars or singletons with.

For more information, read on.

Java Object Proxy Caching

In order to pass Java objects through Ruby call paths in JRuby, we wrap them in a thin wrapper called the "proxy" or "Java object proxy". These wrappers hold the original Java object and allow it to behave like a Ruby object throughout the system.

In JRuby versions 1.6.x and lower, we also cached these proxies in an attempt to ensure the same object would get the same proxy every time it entered Ruby. This was primarily done to support user-defined instance variables or singleton objects on arbitrary Java objects, since it is not possible to actually modify the structure of the Java object.

However, this caching incurred a heavy cost. Each Java object entering Ruby caused the creation of a weak reference and structural elements in an internal map called the ObjectProxyCache. This greatly increased the overhead of receiving objects from Java calls, and potentially hindered efficient garbage collection due to all those weakrefs.

Deprecating Proxy Caching

As of JRuby 9k, the proxy cache will become opt-in on a per-class basis. If you intend to set instance variables or create singletons from Java objects, you'll need to call JavaClassNameHere.__persistent__ = true on the Java class in Ruby code. This will specify that all that class's objects should have their proxies cached.

We will also attempt to turn on this flag lazily, but with a warning. Because objects may enter Ruby through multiple paths before you set an instance variable or make a singleton, we can't guarantee all existing proxies will reflect those lazily-made changes. We recommend setting __persistent__ = true on classes before receiving or constructing instances of them.

See the example above for example usage of __persistent__ = true.

JRuby 1.7 will still cache all proxies by default, but will issue a one-time warning if you're using instance variables or singletons on Java objects. We recommend passing -Xji.objectProxyCache=false to JRuby (or -Djruby.ji.objectProxyCache=false to Java) to find and fix all uses of instance vars or singletons on Java objects in your code.

Alternatives

The simplest alternative would be to store this attached state in a separate structure, like a Hash (properly mutexed) somewhere in the current JRuby environment. This will allow you to localize the caching perf hit to just those objects where you need it.

You may also wish to reference objects weakly, as we did in ObjectProxyCache. The weakling gem provides a solid, consistent weak-reference implementation as well as a WeakHash implementation.

Warning

Whether you set __persistent__ or not, you must keep a reference to the Ruby wrapper object alive in order for it to stay in memory. The caching mechanism JRuby uses allows for either the original Java object or the proxy to be garbage collected if they are no longer referenced, so that the proxy caching does not cause objects to stay alive past their normal lifespan.

Put another way: If you are adding instance variables to or making a singleton object of a Java object, the Ruby object wrapper must stay alive to persist your modifications.

Clone this wiki locally