Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop compatibility with pre-2024-08 remoting releases #757

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions src/main/java/hudson/remoting/Channel.java
Original file line number Diff line number Diff line change
Expand Up @@ -1018,29 +1018,7 @@ public boolean preloadJar(ClassLoader local, URL... jars) throws IOException, In
jars[i] = url;
contents[i] = Util.readFully(url.openStream());
}
try {
return call(new PreloadJarTask2(jars, contents, local));
} catch (IOException ex) {
if (ex.getCause() instanceof IllegalAccessError) {
logger.log(
Level.FINE,
ex,
() -> "Failed to call PreloadJarTask2 on " + this + ", retrying with PreloadJarTask");
// When the agent is running an outdated version of remoting, we cannot access nonpublic classes in the
// same package, as PreloadJarTask2 would be loaded from the controller, and hence a different module/
// classloader, than the rest of remoting. As a result PreloadJarTask2 will throw IllegalAccessError:
//
// java.lang.IllegalAccessError: failed to access class hudson.remoting.RemoteClassLoader from class
// hudson.remoting.PreloadJarTask2 (hudson.remoting.RemoteClassLoader is in unnamed module of loader
// 'app'; hudson.remoting.PreloadJarTask2 is in unnamed module of loader 'Jenkins v${project.version}'
// @795f104a)
//
// Identify this error here and fall back to PreloadJarTask, relying on the restrictive controller-side
// implementation of IClassLoader#fetchJar.
return call(new PreloadJarTask(jars, local));
}
throw ex;
}
return call(new PreloadJarTask2(jars, contents, local));
}

/**
Expand Down
6 changes: 0 additions & 6 deletions src/main/java/hudson/remoting/DumbClassLoaderBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import edu.umd.cs.findbugs.annotations.NonNull;
import java.io.IOException;
import java.net.URL;
import java.util.Map;

/**
Expand All @@ -24,11 +23,6 @@ class DumbClassLoaderBridge implements RemoteClassLoader.IClassLoader {
this.base = base;
}

@Override
public byte[] fetchJar(URL url) throws IOException {
return base.fetchJar(url);
}

@Override
public byte[] fetch(String className) throws ClassNotFoundException {
return base.fetch(className);
Expand Down
15 changes: 0 additions & 15 deletions src/main/java/hudson/remoting/JarURLValidator.java

This file was deleted.

87 changes: 0 additions & 87 deletions src/main/java/hudson/remoting/PreloadJarTask.java

This file was deleted.

4 changes: 0 additions & 4 deletions src/main/java/hudson/remoting/PreloadJarTask2.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@

/**
* {@link Callable} used to deliver a jar file to {@link RemoteClassLoader}.
* <p>
* This replaces {@link hudson.remoting.PreloadJarTask} and delivers the jar contents as part of the Callable rather
* than needing to call {@link hudson.remoting.RemoteClassLoader#prefetch(java.net.URL)}.
* </p>
* @since TODO 2024-08

Check warning on line 34 in src/main/java/hudson/remoting/PreloadJarTask2.java

View check run for this annotation

ci.jenkins.io / Open Tasks Scanner

TODO

NORMAL: 2024-08
*/
final class PreloadJarTask2 implements DelegatingCallable<Boolean, IOException> {
/**
Expand Down
65 changes: 0 additions & 65 deletions src/main/java/hudson/remoting/RemoteClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -675,33 +675,6 @@ public static void deleteDirectoryOnExit(File dir) {
Util.deleteDirectoryOnExit(dir);
}

/**
* Prefetches the jar into this class loader.
*
* @param jar Jar to be prefetched. Note that this file is an file on the other end,
* and doesn't point to anything meaningful locally.
* @return true if the prefetch happened. false if the jar is already prefetched.
* @deprecated Only left in for compatibility with pre-2024-08 remoting. Use {@link #prefetch(java.net.URL, byte[])} instead.
* @see Channel#preloadJar(Callable, Class[])
* @see hudson.remoting.PreloadJarTask
* @see hudson.remoting.PreloadJarTask2
*/
@Deprecated
/*package*/ boolean prefetch(URL jar) throws IOException {
synchronized (prefetchedJars) {
if (prefetchedJars.contains(jar)) {
return false;
}

String p = jar.getPath().replace('\\', '/');
p = Util.getBaseName(p);
File localJar = Util.makeResource(p, proxy.fetchJar(jar));
addURL(localJar.toURI().toURL());
prefetchedJars.add(jar);
return true;
}
}

/**
* Prefetches the specified jar with the specified content into this classloader.
* @param jar Jar to be prefetched. Note that this file is an file on the other end,
Expand Down Expand Up @@ -873,9 +846,6 @@ public static class ClassFile2 extends ResourceFile {
* Remoting interface.
*/
public interface IClassLoader {
@Deprecated
byte[] fetchJar(URL url) throws IOException;

/**
* Retrieves the bytecode of a class.
*/
Expand Down Expand Up @@ -998,31 +968,6 @@ public ClassLoaderProxy(@NonNull ClassLoader cl, Channel channel) {
this.channel = channel;
}

@Override
@SuppressFBWarnings(
value = "URLCONNECTION_SSRF_FD",
justification = "URL validation is being done through JarURLValidator")
public byte[] fetchJar(URL url) throws IOException {
final Object o = channel.getProperty(JarURLValidator.class);
if (o == null) {
final boolean disabled = Boolean.getBoolean(Channel.class.getName() + ".DISABLE_JAR_URL_VALIDATOR");
LOGGER.log(Level.FINE, "Default behavior for URL: " + url + " with disabled flag: " + disabled);
if (!disabled) {
throw new IOException(
"No hudson.remoting.JarURLValidator has been set for this channel, so all #fetchJar calls are rejected."
+ " This is likely a bug in Jenkins."
+ " As a workaround, try updating the agent.jar file.");
}
} else {
if (o instanceof JarURLValidator) {
((JarURLValidator) o).validate(url);
} else {
throw new IOException("Unexpected channel property hudson.remoting.JarURLValidator value: " + o);
}
}
return Util.readFully(url.openStream());
}

@Override
public byte[] fetch(String className) throws ClassNotFoundException {
if (!USE_BOOTSTRAP_CLASSLOADER && cl == PSEUDO_BOOTSTRAP) {
Expand Down Expand Up @@ -1316,11 +1261,6 @@ private RemoteIClassLoader(int oid, IClassLoader proxy) {
this.oid = oid;
}

@Override
public byte[] fetchJar(URL url) throws IOException {
return proxy.fetchJar(url);
}

@Override
public byte[] fetch(String className) throws ClassNotFoundException {
return proxy.fetch(className);
Expand Down Expand Up @@ -1398,11 +1338,6 @@ public Map<String, ClassFile2> fetch3(String className) throws ClassNotFoundExce
throw new ClassNotFoundException(className, cause);
}

@Override
public byte[] fetchJar(URL url) throws IOException {
throw new IOException("Cannot fetch " + url, cause);
}

@Override
public byte[] getResource(String name) throws IOException {
throw new IOException("Cannot get " + name, cause);
Expand Down
Loading