Skip to content

Commit

Permalink
Only set up Java:: constants when accessed directly
Browse files Browse the repository at this point in the history
Previously whenever we see a new type of Java object, we both set
up the proxy class AND set the constant. If that object's class
is not from the typical Java integration classloader hierarchy, it
will pollute the Java:: module with a normally inaccessible entry.

This change only sets up the constant when it is accessed through
the normal package reference, rather than when first seen.
  • Loading branch information
headius committed Apr 24, 2024
1 parent 3fedd5c commit 53861ce
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 13 deletions.
18 changes: 8 additions & 10 deletions core/src/main/java/org/jruby/javasupport/Java.java
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,14 @@ public static RubyModule getProxyClass(Ruby runtime, JavaClass javaClass) {

@SuppressWarnings("deprecation")
public static RubyModule getProxyClass(final Ruby runtime, final Class<?> clazz) {
return getProxyClass(runtime, clazz, false);
}

@SuppressWarnings("deprecation")
public static RubyModule getProxyClass(final Ruby runtime, final Class<?> clazz, boolean setConstant) {
RubyModule proxy = runtime.getJavaSupport().getUnfinishedProxy(clazz);
if (proxy != null) return proxy;
return runtime.getJavaSupport().getProxyClassFromCache(clazz);
return runtime.getJavaSupport().getProxyClassFromCache(clazz, setConstant);
}

// expected to handle Java proxy (Ruby) sub-classes as well
Expand Down Expand Up @@ -473,7 +478,6 @@ private static void generateInterfaceProxy(final Ruby runtime, final Class javaC
proxy.includeModule(extModule);
}
Initializer.setupProxyModule(runtime, javaClass, proxy);
addToJavaPackageModule(proxy);
}

private static void generateClassProxy(Ruby runtime, Class<?> clazz, RubyClass proxy, RubyClass superClass) {
Expand All @@ -495,7 +499,6 @@ else if ( clazz == Object.class ) {
} else {
proxy.getMetaClass().defineAnnotatedMethods(OldStyleExtensionInherited.class);
}
addToJavaPackageModule(proxy);
}
else {
createProxyClass(runtime, proxy, clazz, superClass, false);
Expand All @@ -504,9 +507,6 @@ else if ( clazz == Object.class ) {
for ( int i = interfaces.length; --i >= 0; ) {
proxy.includeModule(getInterfaceModule(runtime, interfaces[i]));
}
if ( Modifier.isPublic(clazz.getModifiers()) ) {
addToJavaPackageModule(proxy);
}
}

// JRUBY-1000, fail early when attempting to subclass a final Java class;
Expand Down Expand Up @@ -824,9 +824,7 @@ private static <T extends ParameterTypes> T checkCallableForArity(final int arit

// package scheme 2: separate module for each full package name, constructed
// from the camel-cased package segments: Java::JavaLang::Object,
private static void addToJavaPackageModule(RubyModule proxyClass) {
final Ruby runtime = proxyClass.getRuntime();
final Class<?> clazz = (Class<?>)proxyClass.dataGetStruct();
static void addToJavaPackageModule(Ruby runtime, Class<?> clazz, RubyModule proxyClass) {
final String fullName;
if ( ( fullName = clazz.getName() ) == null ) return;

Expand Down Expand Up @@ -1074,7 +1072,7 @@ private static RubyModule getProxyClassOrNull(final Ruby runtime, final String c
} catch (ClassNotFoundException ex) { // used to catch NoClassDefFoundError for whatever reason
return null;
}
return getProxyClass(runtime, clazz);
return getProxyClass(runtime, clazz, true);
}

private static int mapMajorMinorClassVersionToJavaVersion(String msg, final int offset) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/javasupport/JavaPackage.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ private RubyModule relativeJavaClassOrPackage(final ThreadContext context,

RubyModule relativeJavaProxyClass(final Ruby runtime, final IRubyObject name) {
final String fullName = packageRelativeName( name.toString() ).toString();
return Java.getProxyClass(runtime, Java.getJavaClass(runtime, fullName));
return Java.getProxyClass(runtime, Java.getJavaClass(runtime, fullName), true);
}

@JRubyMethod(name = "respond_to?")
Expand Down
13 changes: 11 additions & 2 deletions core/src/main/java/org/jruby/javasupport/JavaSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.jruby.util.collections.ClassValueCalculator;

import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -369,8 +370,16 @@ final RubyModule getUnfinishedProxy(Class clazz) {
return null;
}

RubyModule getProxyClassFromCache(Class clazz) {
return proxyClassCache.get(clazz);
RubyModule getProxyClassFromCache(Class clazz, boolean setConstant) {
RubyModule proxy = proxyClassCache.get(clazz);

if (setConstant) {
if ( Modifier.isPublic(clazz.getModifiers()) ) {
Java.addToJavaPackageModule(runtime, clazz, proxy);
}
}

return proxy;
}

}

0 comments on commit 53861ce

Please sign in to comment.