diff --git a/core/src/main/java/hudson/Launcher.java b/core/src/main/java/hudson/Launcher.java index ba599e1753515becf9d52872405c0949558bcdd6..51a918074553404c42b0a252d89f8f7baf8c1213 100644 --- a/core/src/main/java/hudson/Launcher.java +++ b/core/src/main/java/hudson/Launcher.java @@ -39,6 +39,8 @@ import hudson.util.StreamCopyThread; import hudson.util.ArgumentListBuilder; import hudson.util.ProcessTree; import org.apache.commons.io.input.NullInputStream; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import java.io.BufferedOutputStream; import java.io.File; @@ -841,6 +843,30 @@ public abstract class Launcher { } } + @Restricted(NoExternalUse.class) + public static class DummyLauncher extends Launcher { + + public DummyLauncher(TaskListener listener) { + super(listener, null); + } + + @Override + public Proc launch(ProcStarter starter) throws IOException { + throw new IOException("Can not call launch on a dummy launcher."); + } + + @Override + public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map envVars) throws IOException, InterruptedException { + throw new IOException("Can not call launchChannel on a dummy launcher."); + } + + @Override + public void kill(Map modelEnvVars) throws IOException, InterruptedException { + // Kill method should do nothing. + } + } + + /** * Launches processes remotely by using the given channel. */ diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java index 5e9204f0a0b76582e4162e2b6bacaf566eb3efee..e52a6f8af5261614a52a67d36170012d293811e9 100644 --- a/core/src/main/java/hudson/model/Slave.java +++ b/core/src/main/java/hudson/model/Slave.java @@ -343,9 +343,21 @@ public abstract class Slave extends Node implements Serializable { } + /** + * Creates a launcher for the slave. + * + * @return + * If there is no computer it will return a {@link hudson.Launcher.DummyLauncher}, otherwise it + * will return a {@link hudson.Launcher.RemoteLauncher} instead. + */ public Launcher createLauncher(TaskListener listener) { SlaveComputer c = getComputer(); - return new RemoteLauncher(listener, c.getChannel(), c.isUnix()).decorateFor(this); + if (c == null) { + listener.error("Issue with creating launcher for slave " + name + "."); + return new Launcher.DummyLauncher(listener); + } else { + return new RemoteLauncher(listener, c.getChannel(), c.isUnix()).decorateFor(this); + } } /**