Slave.JnlpJar.getURL did not work in some modes when core had a snapshot dependency on Remoting.
@@ -31,6 +31,7 @@ import hudson.FilePath;
import hudson.Launcher;
import hudson.Launcher.RemoteLauncher;
import hudson.Util;
+import hudson.cli.CLI;
import hudson.model.Descriptor.FormException;
import hudson.remoting.Callable;
import hudson.remoting.Channel;
@@ -47,6 +48,7 @@ import hudson.util.ClockDifference;
import hudson.util.DescribableList;
import hudson.util.FormValidation;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
@@ -57,6 +59,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.CheckForNull;
@@ -398,20 +402,58 @@ public abstract class Slave extends Node implements Serializable {
throw new MalformedURLException("The specified file path " + fileName + " is not allowed due to security reasons");
}
- if (name.equals("hudson-cli.jar")) {
+ if (name.equals("hudson-cli.jar") || name.equals("jenkins-cli.jar")) {
+ File cliJar = Which.jarFile(CLI.class);
+ if (cliJar.isFile()) {
name = "jenkins-cli.jar";
+ } else {
+ URL res = findExecutableJar(cliJar, CLI.class);
+ if (res != null) {
+ return res;
+ }
+ }
} else if (name.equals("agent.jar") || name.equals("slave.jar") || name.equals("remoting.jar")) {
- name = "lib/" + Which.jarFile(Channel.class).getName();
+ File remotingJar = Which.jarFile(hudson.remoting.Launcher.class);
+ if (remotingJar.isFile()) {
+ name = "lib/" + remotingJar.getName();
+ } else {
+ URL res = findExecutableJar(remotingJar, hudson.remoting.Launcher.class);
+ if (res != null) {
+ return res;
+ }
+ }
}
URL res = Jenkins.getInstance().servletContext.getResource("/WEB-INF/" + name);
if(res==null) {
- // during the development this path doesn't have the files.
- res = new URL(new File(".").getAbsoluteFile().toURI().toURL(),"target/jenkins/WEB-INF/"+name);
+ throw new FileNotFoundException(name); // giving up
+ } else {
+ LOGGER.log(Level.FINE, "found {0}", res);
}
return res;
}
+ /** Useful for {@code JenkinsRule.createSlave}, {@code hudson-dev:run}, etc. */
+ private @CheckForNull URL findExecutableJar(File notActuallyJAR, Class<?> mainClass) throws IOException {
+ if (notActuallyJAR.getName().equals("classes")) {
+ File[] siblings = notActuallyJAR.getParentFile().listFiles();
+ if (siblings != null) {
+ for (File actualJar : siblings) {
+ if (actualJar.getName().endsWith(".jar")) {
+ try (JarFile jf = new JarFile(actualJar, false)) {
+ Manifest mf = jf.getManifest();
+ if (mf != null && mainClass.getName().equals(mf.getMainAttributes().getValue("Main-Class"))) {
+ LOGGER.log(Level.FINE, "found {0}", actualJar);
+ return actualJar.toURI().toURL();
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
public byte[] readFully() throws IOException {
try (InputStream in = connect().getInputStream()) {
return IOUtils.toByteArray(in);
