From afba3846c4ec4eda5c4cde9df6610fa79f9a3147 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Mon, 18 Dec 2023 12:10:22 +0800 Subject: [PATCH] Try to find class resource to avoid exception The exception thrown here when we cannot find a class can be very expensive at boot time. For most third-party extensions, this exception will be raised twice for every bound method, due to double-checking the classloader under lock a second time. By first looking for a .class resource, we can avoid the expensive exception if it is unlikely to succeed. --- .../runtime/methods/InvocationMethodFactory.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) 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 d5095981d70b..e825b16c885a 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 @@ -56,6 +56,7 @@ import java.io.PrintWriter; import java.lang.reflect.Modifier; +import java.net.URL; import java.util.Collections; import java.util.List; @@ -634,11 +635,13 @@ private static void loadReceiver(String typePath, JavaMethodDescriptor desc, Ski private Class tryClass(String name, Class targetClass, Class expectedSuperclass) { final Class c; try { - if (classLoader == null) { - c = Class.forName(name, true, classLoader); - } else { - c = classLoader.loadClass(name); + URL resource = classLoader.findResource(name.replace('.', '/')); + if (resource == null) { + if (DEBUG) LOG.debug("could not find class file for " + name); + seenUndefinedClasses = true; + return null; } + c = classLoader.loadClass(name); } catch (ClassNotFoundException e) { if (DEBUG) LOG.debug(e); seenUndefinedClasses = true;