From fe5ce630159138441898329ceb5c381e22c09fe0 Mon Sep 17 00:00:00 2001 From: James Nord Date: Tue, 14 May 2024 13:42:02 +0100 Subject: [PATCH 1/2] pass through the remote ClassLoaders name add getName to the IClassloader and set a name in the RemoteClassLoader This improves the debugability from RemoteClassloaders to understand any classloading related issues. --- .../remoting/DumbClassLoaderBridge.java | 6 ++++ .../hudson/remoting/RemoteClassLoader.java | 34 +++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/main/java/hudson/remoting/DumbClassLoaderBridge.java b/src/main/java/hudson/remoting/DumbClassLoaderBridge.java index 090a60171..4dd43aee9 100644 --- a/src/main/java/hudson/remoting/DumbClassLoaderBridge.java +++ b/src/main/java/hudson/remoting/DumbClassLoaderBridge.java @@ -79,4 +79,10 @@ public ResourceFile[] getResources2(String name) throws IOException { } return res; } + + @Override + public String getName() throws IOException { + return base.getName(); + } + } diff --git a/src/main/java/hudson/remoting/RemoteClassLoader.java b/src/main/java/hudson/remoting/RemoteClassLoader.java index 84518a82c..06db8e6b3 100644 --- a/src/main/java/hudson/remoting/RemoteClassLoader.java +++ b/src/main/java/hudson/remoting/RemoteClassLoader.java @@ -170,11 +170,18 @@ public static ClassLoader create(@CheckForNull ClassLoader parent, @NonNull ICla // actually our classloader that we exported to the other side. return ((ClassLoaderProxy) proxy).cl; } - return new RemoteClassLoader(parent, proxy); + + String name; + try { + name = proxy.getName(); + } catch(IOException ignored) { + name = "unknown-due-to-io-error"; + } + return new RemoteClassLoader(name, parent, proxy); } - private RemoteClassLoader(@CheckForNull ClassLoader parent, @NonNull IClassLoader proxy) { - super(new URL[0], parent); + private RemoteClassLoader(String name, @CheckForNull ClassLoader parent, @NonNull IClassLoader proxy) { + super(name, new URL[0], parent); final Channel channel = RemoteInvocationHandler.unwrap(proxy); this.channel = channel == null ? null : channel.ref(); this.underlyingProxy = proxy; @@ -887,6 +894,12 @@ public interface IClassLoader { */ @NonNull ResourceFile[] getResources2(String name) throws IOException; + + /** + * Name of the classLoader + * @since 3242 + */ + String getName() throws IOException; } /** @@ -1178,6 +1191,11 @@ public ResourceFile[] getResources2(String name) throws IOException { return r; } + @Override + public String getName() throws IOException { + return cl.getName(); + } + @Override public boolean equals(Object that) { if (this == that) { @@ -1276,6 +1294,11 @@ public ResourceFile[] getResources2(String name) throws IOException { return proxy.getResources2(name); } + @Override + public String getName() throws IOException { + return proxy.getName(); + } + private Object readResolve() throws ObjectStreamException { try { return getChannelForSerialization().getExportedObject(oid); @@ -1336,6 +1359,11 @@ public ResourceFile[] getResources2(String name) throws IOException { throw new IOException("Cannot get " + name, cause); } + @Override + public String getName() throws IOException { + throw new IOException("Cannot getName", cause); + } + } private static Iterable analyze(InputStream bytecode) { From 98cc05c5d792aa27fb19cb80a3f00b401d165b1b Mon Sep 17 00:00:00 2001 From: James Nord Date: Wed, 15 May 2024 14:45:44 +0100 Subject: [PATCH 2/2] Make "unknown" classloader unique If we can not obtain the name of the classloader then add the proxies identityHashCode so they will be unique amongst all others. --- src/main/java/hudson/remoting/RemoteClassLoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/hudson/remoting/RemoteClassLoader.java b/src/main/java/hudson/remoting/RemoteClassLoader.java index 06db8e6b3..b54e4652e 100644 --- a/src/main/java/hudson/remoting/RemoteClassLoader.java +++ b/src/main/java/hudson/remoting/RemoteClassLoader.java @@ -44,6 +44,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.Vector; @@ -175,7 +176,7 @@ public static ClassLoader create(@CheckForNull ClassLoader parent, @NonNull ICla try { name = proxy.getName(); } catch(IOException ignored) { - name = "unknown-due-to-io-error"; + name = String.format(Locale.ROOT, "unknown-due-to-io-error %1$#x", System.identityHashCode(proxy)); } return new RemoteClassLoader(name, parent, proxy); }