diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index 7f62a9e244..a7f3259bb5 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -641,9 +641,7 @@ public class ClassicPluginStrategy implements PluginStrategy { if (PluginManager.FAST_LOOKUP) { for (PluginWrapper pw : getTransitiveDependencies()) { try { - Class c = ClassLoaderReflectionToolkit._findLoadedClass(pw.classLoader, name); - if (c!=null) return c; - return ClassLoaderReflectionToolkit._findClass(pw.classLoader, name); + return ClassLoaderReflectionToolkit.loadClass(pw.classLoader, name); } catch (ClassNotFoundException ignored) { //not found. try next } diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 47bb91c8ed..1d780278df 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -2197,15 +2197,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas if (FAST_LOOKUP) { for (PluginWrapper p : activePlugins) { try { - Class c = ClassLoaderReflectionToolkit._findLoadedClass(p.classLoader, name); - if (c != null) { - synchronized (loaded) { - loaded.put(name, c); - } - return c; - } - // calling findClass twice appears to cause LinkageError: duplicate class def - c = ClassLoaderReflectionToolkit._findClass(p.classLoader, name); + Class c = ClassLoaderReflectionToolkit.loadClass(p.classLoader, name); synchronized (loaded) { loaded.put(name, c); } diff --git a/core/src/main/java/jenkins/ClassLoaderReflectionToolkit.java b/core/src/main/java/jenkins/ClassLoaderReflectionToolkit.java index 42b0134522..edce6b431a 100644 --- a/core/src/main/java/jenkins/ClassLoaderReflectionToolkit.java +++ b/core/src/main/java/jenkins/ClassLoaderReflectionToolkit.java @@ -70,6 +70,7 @@ public class ClassLoaderReflectionToolkit { /** * Calls {@link ClassLoader#findLoadedClass} while holding {@link ClassLoader#getClassLoadingLock}. * @since 1.553 + * @deprecated use {@link #loadClass(ClassLoader, String)} */ public static @CheckForNull Class _findLoadedClass(ClassLoader cl, String name) { synchronized (getClassLoadingLock(cl, name)) { @@ -100,6 +101,7 @@ public class ClassLoaderReflectionToolkit { /** * Calls {@link ClassLoader#findClass} while holding {@link ClassLoader#getClassLoadingLock}. * @since 1.553 + * @deprecated use {@link #loadClass(ClassLoader, String)} */ public static @NonNull Class _findClass(ClassLoader cl, String name) throws ClassNotFoundException { synchronized (getClassLoadingLock(cl, name)) { @@ -124,6 +126,48 @@ public class ClassLoaderReflectionToolkit { } } + /** + * Load the class with the specified binary name. This method searches for classes in the + * following order: + * + *
    + *
  1. + *

    Invoke {@link ClassLoader#findLoadedClass(String)} to check if the class has already + * been loaded. + *

  2. + *

    Invoke the {@link ClassLoader#findClass(String)} method to find the class. + *

+ * + *

This method synchronizes on the result of {@link ClassLoader#getClassLoadingLock(String)} + * during the entire class loading process. + * + * @param cl The {@link ClassLoader} to use. + * @param name The binary name of the class. + * @return The resulting {@link Class} object. + * @throws ClassNotFoundException If the class could not be found. + * @since 2.TODO + */ + public static @NonNull Class loadClass(ClassLoader cl, String name) throws ClassNotFoundException { + synchronized (getClassLoadingLock(cl, name)) { + // First, check if the class has already been loaded. + Class c; + if (cl instanceof JenkinsClassLoader) { + c = ((JenkinsClassLoader) cl).findLoadedClass2(name); + } else { + c = (Class) invoke(FindLoadedClass.FIND_LOADED_CLASS, RuntimeException.class, cl, name); + } + if (c != null) { + return c; + } + + // Find the class. + if (cl instanceof JenkinsClassLoader) { + return ((JenkinsClassLoader) cl).findClass(name); + } else { + return (Class) invoke(FindClass.FIND_CLASS, ClassNotFoundException.class, cl, name); + } + } + } /** * Calls {@link ClassLoader#findResource}.