From 90b69aaccb7b807065b4f3facaeb08078e02f2b8 Mon Sep 17 00:00:00 2001 From: James Nord Date: Tue, 14 May 2024 17:10:16 +0100 Subject: [PATCH 1/7] Ensure Classloaders have names for debugging --- .../java/hudson/ClassicPluginStrategy.java | 30 +++++++++++++++---- .../java/hudson/PluginFirstClassLoader2.java | 5 ++-- core/src/main/java/hudson/PluginManager.java | 4 +-- .../java/hudson/util/MaskingClassLoader.java | 2 +- .../java/jenkins/util/URLClassLoader2.java | 29 ++++++++++++++++++ .../test/java/hudson/PluginWrapperTest.java | 2 +- pom.xml | 2 +- war/src/main/java/executable/Main.java | 2 +- 8 files changed, 62 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index 10b0d179fdd7..f58184a2c0fa 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -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; @@ -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 optionalDependencies) { @@ -263,15 +268,28 @@ public static List 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 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 paths, ClassLoader parent, Attributes atts) throws IOException { + // generate a legacy id so at least we can track to something + return createClassLoader("legacy"+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 paths, ClassLoader parent, Attributes atts) throws IOException { boolean usePluginFirstClassLoader = atts != null && Boolean.parseBoolean(atts.getValue("PluginFirstClassLoader")); @@ -285,9 +303,9 @@ protected ClassLoader createClassLoader(List 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; } @@ -561,7 +579,7 @@ static final class DependencyClassLoader extends ClassLoader { } DependencyClassLoader(ClassLoader parent, File archive, List dependencies, PluginManager pluginManager) { - super(parent); + super("dependency ClassLoader for " + archive.getPath(), parent); this._for = archive; this.dependencies = List.copyOf(dependencies); this.pluginManager = pluginManager; diff --git a/core/src/main/java/hudson/PluginFirstClassLoader2.java b/core/src/main/java/hudson/PluginFirstClassLoader2.java index 974939d53acb..30618835c8a7 100644 --- a/core/src/main/java/hudson/PluginFirstClassLoader2.java +++ b/core/src/main/java/hudson/PluginFirstClassLoader2.java @@ -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)); } /** diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 1fd5358454a6..34c80912bd09 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -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); @@ -2337,7 +2337,7 @@ public static final class UberClassLoader extends ClassLoader { } public UberClassLoader(List activePlugins) { - super(PluginManager.class.getClassLoader()); + super(activePlugins.stream().map(PluginWrapper::getShortName).collect(Collectors.joining(", ", "UberClassLoader for ", "")), PluginManager.class.getClassLoader()); this.activePlugins = activePlugins; } diff --git a/core/src/main/java/hudson/util/MaskingClassLoader.java b/core/src/main/java/hudson/util/MaskingClassLoader.java index 74bbbe1a9863..dfad754fc170 100644 --- a/core/src/main/java/hudson/util/MaskingClassLoader.java +++ b/core/src/main/java/hudson/util/MaskingClassLoader.java @@ -59,7 +59,7 @@ public MaskingClassLoader(ClassLoader parent, String... masks) { } public MaskingClassLoader(ClassLoader parent, Collection masks) { - super(parent); + super("Masking ClassLoader of " + parent.getName(), parent); this.masksClasses = List.copyOf(masks); /* diff --git a/core/src/main/java/jenkins/util/URLClassLoader2.java b/core/src/main/java/jenkins/util/URLClassLoader2.java index 72611bc49432..e25f6ea653f8 100644 --- a/core/src/main/java/jenkins/util/URLClassLoader2.java +++ b/core/src/main/java/jenkins/util/URLClassLoader2.java @@ -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); diff --git a/core/src/test/java/hudson/PluginWrapperTest.java b/core/src/test/java/hudson/PluginWrapperTest.java index 32c24d8abf36..c33877a3b6fe 100644 --- a/core/src/test/java/hudson/PluginWrapperTest.java +++ b/core/src/test/java/hudson/PluginWrapperTest.java @@ -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); } } diff --git a/pom.xml b/pom.xml index 46793065ac9e..9e302e9567cf 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ THE SOFTWARE. https://www.jenkins.io/changelog - 3206.vb_15dcf73f6a_9 + 3229.v96d6148deb_f9 4.13 diff --git a/war/src/main/java/executable/Main.java b/war/src/main/java/executable/Main.java index a746a28a4ee6..410392f96202 100644 --- a/war/src/main/java/executable/Main.java +++ b/war/src/main/java/executable/Main.java @@ -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); } From 34cd0b67498b07f00a8ec3b2fd9d7536003a55e0 Mon Sep 17 00:00:00 2001 From: James Nord Date: Wed, 15 May 2024 11:24:55 +0100 Subject: [PATCH 2/7] update incremental version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9e302e9567cf..50cf2563537b 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ THE SOFTWARE. https://www.jenkins.io/changelog - 3229.v96d6148deb_f9 + 3242.vfe5ce6301591 4.13 From 070fc9371e0c8b84ec965ad36ef6216b20d1b7c7 Mon Sep 17 00:00:00 2001 From: James Nord Date: Wed, 15 May 2024 14:25:19 +0100 Subject: [PATCH 3/7] simplify name of UberClassloader and update since TODOs Co-authored-by: Jesse Glick --- core/src/main/java/hudson/ClassicPluginStrategy.java | 8 ++++---- core/src/main/java/hudson/PluginManager.java | 2 +- core/src/main/java/jenkins/util/URLClassLoader2.java | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index f58184a2c0fa..d9b37f0fac29 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -271,7 +271,7 @@ public static List getImpliedDependencies(String plugi /** * @deprecated since TODO use {@link #createClassLoader(String, List, ClassLoader, Attributes)} */ - @Deprecated(since = "//TODO") + @Deprecated(since = "TODO") protected ClassLoader createClassLoader(List paths, ClassLoader parent) throws IOException { return createClassLoader(paths, parent, null); } @@ -279,15 +279,15 @@ protected ClassLoader createClassLoader(List paths, ClassLoader parent) th /** * @deprecated since TODO use {@link #createClassLoader(String, List, ClassLoader, Attributes)} */ - @Deprecated(since="@TODO") + @Deprecated(since="TODO") protected ClassLoader createClassLoader(List paths, ClassLoader parent, Attributes atts) throws IOException { // generate a legacy id so at least we can track to something - return createClassLoader("legacy"+UUID.randomUUID(), paths, parent, atts); + 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 + * @since TODO */ protected ClassLoader createClassLoader(String name, List paths, ClassLoader parent, Attributes atts) throws IOException { boolean usePluginFirstClassLoader = diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 34c80912bd09..0cb02b65b9c1 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -2337,7 +2337,7 @@ public static final class UberClassLoader extends ClassLoader { } public UberClassLoader(List activePlugins) { - super(activePlugins.stream().map(PluginWrapper::getShortName).collect(Collectors.joining(", ", "UberClassLoader for ", "")), PluginManager.class.getClassLoader()); + super("UberClassLoader", PluginManager.class.getClassLoader()); this.activePlugins = activePlugins; } diff --git a/core/src/main/java/jenkins/util/URLClassLoader2.java b/core/src/main/java/jenkins/util/URLClassLoader2.java index e25f6ea653f8..3fdedcbeada0 100644 --- a/core/src/main/java/jenkins/util/URLClassLoader2.java +++ b/core/src/main/java/jenkins/util/URLClassLoader2.java @@ -20,7 +20,7 @@ public class URLClassLoader2 extends URLClassLoader implements JenkinsClassLoade /** * @deprecated use {@link URLClassLoader2#URLClassLoader2(String, URL[])} */ - @Deprecated(since = "//TODO") + @Deprecated(since = "TODO") public URLClassLoader2(URL[] urls) { super(urls); } @@ -28,7 +28,7 @@ public URLClassLoader2(URL[] urls) { /** * @deprecated use {@link URLClassLoader2#URLClassLoader2(String, URL[], ClassLoader)} */ - @Deprecated(since = "//TODO") + @Deprecated(since = "TODO") public URLClassLoader2(URL[] urls, ClassLoader parent) { super(urls, parent); } @@ -37,7 +37,7 @@ public URLClassLoader2(URL[] urls, ClassLoader 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 + * @since TODO */ public URLClassLoader2(String name, URL[] urls) { super(name, urls, getSystemClassLoader()); @@ -48,7 +48,7 @@ public URLClassLoader2(String name, URL[] urls) { * @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 + * @since TODO */ public URLClassLoader2(String name, URL[] urls, ClassLoader parent) { super(name, urls, parent); From e11dd4687d36f37373054db468fa6d76b8162600 Mon Sep 17 00:00:00 2001 From: James Nord Date: Wed, 15 May 2024 17:13:02 +0100 Subject: [PATCH 4/7] use released version of remoting --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 50cf2563537b..4a7e164406a0 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ THE SOFTWARE. https://www.jenkins.io/changelog - 3242.vfe5ce6301591 + 3244.vf7f977e04755 4.13 From b0a058ff844e27ab102cb406d77cbe9078ddebff Mon Sep 17 00:00:00 2001 From: James Nord Date: Wed, 15 May 2024 17:21:50 +0100 Subject: [PATCH 5/7] set the minimum version of remoting --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4a7e164406a0..a4c7b89bcaf5 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ THE SOFTWARE. 3244.vf7f977e04755 - 4.13 + 3244.vf7f977e04755 Max Medium From e0c32113b283285c009f5421548fbc5ac1217614 Mon Sep 17 00:00:00 2001 From: James Nord Date: Wed, 15 May 2024 19:49:05 +0100 Subject: [PATCH 6/7] pick up backward compatable remoting version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a4c7b89bcaf5..8047d72626c1 100644 --- a/pom.xml +++ b/pom.xml @@ -87,9 +87,9 @@ THE SOFTWARE. https://www.jenkins.io/changelog - 3244.vf7f977e04755 + 3247.v5472f9a_4131a_ - 3244.vf7f977e04755 + 4.13 Max Medium From 8c3eedb03b06a5e8abeeeda92947642445ced221 Mon Sep 17 00:00:00 2001 From: James Nord Date: Thu, 16 May 2024 14:33:01 +0100 Subject: [PATCH 7/7] update from remoting incremental version to release version https://github.com/jenkinsci/remoting/releases/tag/3248.v65ecb_254c298 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8047d72626c1..7ded53430fa9 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ THE SOFTWARE. https://www.jenkins.io/changelog - 3247.v5472f9a_4131a_ + 3248.v65ecb_254c298 4.13