diff --git a/core/src/main/java/org/jruby/internal/runtime/methods/InvocationMethodFactory.java b/core/src/main/java/org/jruby/internal/runtime/methods/InvocationMethodFactory.java index 82f90ba5f44..81f6c7b815d 100644 --- a/core/src/main/java/org/jruby/internal/runtime/methods/InvocationMethodFactory.java +++ b/core/src/main/java/org/jruby/internal/runtime/methods/InvocationMethodFactory.java @@ -635,9 +635,8 @@ private static void loadReceiver(String typePath, JavaMethodDescriptor desc, Ski private Class tryClass(String name, String path, Class targetClass, Class expectedSuperclass) { final Class c; try { - URL resource = classLoader.findResource(path + ".class"); - if (resource == null) { - if (DEBUG) LOG.debug("could not find class file for " + name); + if (!classLoader.hasClass(name)) { + if (DEBUG) System.err.println("could not find class file for " + name); seenUndefinedClasses = true; return null; } diff --git a/core/src/main/java/org/jruby/util/ClassDefiningJRubyClassLoader.java b/core/src/main/java/org/jruby/util/ClassDefiningJRubyClassLoader.java index 71cdc09d33b..164bcc97ca0 100644 --- a/core/src/main/java/org/jruby/util/ClassDefiningJRubyClassLoader.java +++ b/core/src/main/java/org/jruby/util/ClassDefiningJRubyClassLoader.java @@ -30,11 +30,16 @@ import java.net.URL; import java.net.URLClassLoader; import java.security.ProtectionDomain; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentSkipListSet; public class ClassDefiningJRubyClassLoader extends URLClassLoader implements ClassDefiningClassLoader { public final static ProtectionDomain DEFAULT_DOMAIN; + private final Set definedClasses = new ConcurrentSkipListSet<>(); + static { ProtectionDomain defaultDomain = null; try { @@ -50,10 +55,24 @@ public ClassDefiningJRubyClassLoader(ClassLoader parent) { } public Class defineClass(String name, byte[] bytes) { - return super.defineClass(name, bytes, 0, bytes.length, DEFAULT_DOMAIN); + Class aClass = super.defineClass(name, bytes, 0, bytes.length, DEFAULT_DOMAIN); + definedClasses.add(name); + return aClass; } public Class defineClass(String name, byte[] bytes, ProtectionDomain domain) { - return super.defineClass(name, bytes, 0, bytes.length, domain); + Class aClass = super.defineClass(name, bytes, 0, bytes.length, domain); + definedClasses.add(name); + return aClass; + } + + /** + * Return true if the class is loadable in this classloader, false otherwise. + * + * @param name the class name + * @return whether it's loadable + */ + public boolean hasClass(String name) { + return definedClasses.contains(name) || super.findResource(name.replace('.', '/') + ".class") != null; } }