Skip to content

Commit

Permalink
Ensure ClassLoaders have names for debugging (#9277)
Browse files Browse the repository at this point in the history
* Ensure Classloaders have names for debugging

* update incremental version

* simplify name of UberClassloader and update since TODOs

Co-authored-by: Jesse Glick <jglick@cloudbees.com>

* use released version of remoting

* set the minimum version of remoting

* pick up backward compatable remoting version

* update from remoting incremental version to release version

https://github.com/jenkinsci/remoting/releases/tag/3248.v65ecb_254c298

---------

Co-authored-by: Jesse Glick <jglick@cloudbees.com>
  • Loading branch information
jtnord and jglick authored May 18, 2024
1 parent aaf4b64 commit 94f7154
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 14 deletions.
30 changes: 24 additions & 6 deletions core/src/main/java/hudson/ClassicPluginStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
Expand Down Expand Up @@ -235,7 +236,11 @@ private static Manifest loadLinkedManifest(File archive) throws IOException {
dependencyLoader = getBaseClassLoader(atts, dependencyLoader);

return new PluginWrapper(pluginManager, archive, manifest, baseResourceURL,
createClassLoader(paths, dependencyLoader, atts), disableFile, dependencies, optionalDependencies);
createClassLoader(computeClassLoaderName(manifest, archive), paths, dependencyLoader, atts), disableFile, dependencies, optionalDependencies);
}

private static String computeClassLoaderName(Manifest mf, File archive) {
return "PluginClassLoader for " + PluginWrapper.computeShortName(mf, archive.getName());
}

private void fix(Attributes atts, List<PluginWrapper.Dependency> optionalDependencies) {
Expand Down Expand Up @@ -263,15 +268,28 @@ public static List<PluginWrapper.Dependency> getImpliedDependencies(String plugi
return DetachedPluginsUtil.getImpliedDependencies(pluginName, jenkinsVersion);
}

@Deprecated
/**
* @deprecated since TODO use {@link #createClassLoader(String, List, ClassLoader, Attributes)}
*/
@Deprecated(since = "TODO")
protected ClassLoader createClassLoader(List<File> paths, ClassLoader parent) throws IOException {
return createClassLoader(paths, parent, null);
}

/**
* Creates the classloader that can load all the specified jar files and delegate to the given parent.
* @deprecated since TODO use {@link #createClassLoader(String, List, ClassLoader, Attributes)}
*/
@Deprecated(since="TODO")
protected ClassLoader createClassLoader(List<File> paths, ClassLoader parent, Attributes atts) throws IOException {
// generate a legacy id so at least we can track to something
return createClassLoader("unidentified-" + UUID.randomUUID(), paths, parent, atts);
}

/**
* Creates a classloader that can load all the specified jar files and delegate to the given parent.
* @since TODO
*/
protected ClassLoader createClassLoader(String name, List<File> paths, ClassLoader parent, Attributes atts) throws IOException {
boolean usePluginFirstClassLoader =
atts != null && Boolean.parseBoolean(atts.getValue("PluginFirstClassLoader"));

Expand All @@ -285,9 +303,9 @@ protected ClassLoader createClassLoader(List<File> paths, ClassLoader parent, At
}
URLClassLoader2 classLoader;
if (usePluginFirstClassLoader) {
classLoader = new PluginFirstClassLoader2(urls.toArray(new URL[0]), parent);
classLoader = new PluginFirstClassLoader2(name, urls.toArray(new URL[0]), parent);
} else {
classLoader = new URLClassLoader2(urls.toArray(new URL[0]), parent);
classLoader = new URLClassLoader2(name, urls.toArray(new URL[0]), parent);
}
return classLoader;
}
Expand Down Expand Up @@ -561,7 +579,7 @@ static final class DependencyClassLoader extends ClassLoader {
}

DependencyClassLoader(ClassLoader parent, File archive, List<Dependency> dependencies, PluginManager pluginManager) {
super(parent);
super("dependency ClassLoader for " + archive.getPath(), parent);
this._for = archive;
this.dependencies = List.copyOf(dependencies);
this.pluginManager = pluginManager;
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/hudson/PluginFirstClassLoader2.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ public class PluginFirstClassLoader2 extends URLClassLoader2 {
registerAsParallelCapable();
}

public PluginFirstClassLoader2(@NonNull URL[] urls, @NonNull ClassLoader parent) {
super(Objects.requireNonNull(urls), Objects.requireNonNull(parent));

public PluginFirstClassLoader2(String name, @NonNull URL[] urls, @NonNull ClassLoader parent) {
super(name, Objects.requireNonNull(urls), Objects.requireNonNull(parent));
}

/**
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/hudson/PluginManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ protected void copyBundledPlugin(URL src, String fileName) throws IOException {
}

/*package*/ static @CheckForNull Manifest parsePluginManifest(URL bundledJpi) {
try (URLClassLoader cl = new URLClassLoader(new URL[]{bundledJpi})) {
try (URLClassLoader cl = new URLClassLoader("Temporary classloader for parsing " + bundledJpi.toString(), new URL[]{bundledJpi}, ClassLoader.getSystemClassLoader())) {
InputStream in = null;
try {
URL res = cl.findResource(PluginWrapper.MANIFEST_FILENAME);
Expand Down Expand Up @@ -2337,7 +2337,7 @@ public static final class UberClassLoader extends ClassLoader {
}

public UberClassLoader(List<PluginWrapper> activePlugins) {
super(PluginManager.class.getClassLoader());
super("UberClassLoader", PluginManager.class.getClassLoader());
this.activePlugins = activePlugins;
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/hudson/util/MaskingClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public MaskingClassLoader(ClassLoader parent, String... masks) {
}

public MaskingClassLoader(ClassLoader parent, Collection<String> masks) {
super(parent);
super("Masking ClassLoader of " + parent.getName(), parent);
this.masksClasses = List.copyOf(masks);

/*
Expand Down
29 changes: 29 additions & 0 deletions core/src/main/java/jenkins/util/URLClassLoader2.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,43 @@ public class URLClassLoader2 extends URLClassLoader implements JenkinsClassLoade
registerAsParallelCapable();
}

/**
* @deprecated use {@link URLClassLoader2#URLClassLoader2(String, URL[])}
*/
@Deprecated(since = "TODO")
public URLClassLoader2(URL[] urls) {
super(urls);
}

/**
* @deprecated use {@link URLClassLoader2#URLClassLoader2(String, URL[], ClassLoader)}
*/
@Deprecated(since = "TODO")
public URLClassLoader2(URL[] urls, ClassLoader parent) {
super(urls, parent);
}

/**
* Create a new {@link URLClassLoader2} with the given name and URLS and the {@link #getSystemClassLoader()} as its parent.
* @param name name of this classloader.
* @param urls the list of URLS to find classes in.
* @since TODO
*/
public URLClassLoader2(String name, URL[] urls) {
super(name, urls, getSystemClassLoader());
}

/**
* Create a new {@link URLClassLoader2} with the given name, URLS parent.
* @param name name of this classloader.
* @param urls the list of URLS to find classes in.
* @param parent the parent to search for classes before we look in the {@code urls}
* @since TODO
*/
public URLClassLoader2(String name, URL[] urls, ClassLoader parent) {
super(name, urls, parent);
}

@Override
public void addURL(URL url) {
super.addURL(url);
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/hudson/PluginWrapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public void dependencyFailedToLoad() {
@Issue("JENKINS-66563")
@Test
public void insertJarsIntoClassPath() throws Exception {
try (URLClassLoader2 cl = new URLClassLoader2(new URL[0])) {
try (URLClassLoader2 cl = new URLClassLoader2("Test", new URL[0])) {
assertInjectingJarsWorks(cl);
}
}
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ THE SOFTWARE.
<changelog.url>https://www.jenkins.io/changelog</changelog.url>

<!-- Bundled Remoting version -->
<remoting.version>3206.vb_15dcf73f6a_9</remoting.version>
<remoting.version>3248.v65ecb_254c298</remoting.version>
<!-- Minimum Remoting version, which is tested for API compatibility -->
<remoting.minimum.supported.version>4.13</remoting.minimum.supported.version>

Expand Down
2 changes: 1 addition & 1 deletion war/src/main/java/executable/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public static void main(String[] args) throws IllegalAccessException {
// locate the Winstone launcher
ClassLoader cl;
try {
cl = new URLClassLoader(new URL[] {tmpJar.toURI().toURL()});
cl = new URLClassLoader("Jenkins Main ClassLoader", new URL[] {tmpJar.toURI().toURL()}, ClassLoader.getSystemClassLoader());
} catch (MalformedURLException e) {
throw new UncheckedIOException(e);
}
Expand Down

0 comments on commit 94f7154

Please sign in to comment.