提交 288b8d0b 编写于 作者: J Jesse Glick

[FIXED JENKINS-18403] Detect when an attempt is made to run Maven on JDK 5.

If so, retry with (6+) slave JVM, setting maven-{compiler,surefire}-plugin properties to point to original.
上级 6fafc8c4
......@@ -61,6 +61,9 @@ Upcoming changes</a>
<li class=bug>
<code>JENKINS_DEBUG_LEVEL</code> misinterpreted by Winstone, causing excessive logging.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-18701">issue 18701</a>)
<li class='major bug'>
Since 1.520, Jenkins requires Java 6 or later, breaking Maven builds set to use JDK 5. Now falls back to JVM of slave agent but sets compile/test flags to use defined JDK.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-18403">issue 18403</a>)
<li class=bug>
Provided maven settings.xml in maven builder is lost.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-15976">issue 15976</a>)
......
......@@ -29,6 +29,7 @@ import hudson.tasks._maven.MavenConsoleAnnotator;
import hudson.util.ArgumentListBuilder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
......@@ -211,7 +212,6 @@ public abstract class AbstractMavenProcessFactory
listener.getLogger().println("Using env variables: "+ envVars);
try {
//launcher.getChannel().export( type, instance )
final Acceptor acceptor = launcher.getChannel().call(new SocketHandler());
Charset charset;
try {
charset = Charset.forName(launcher.getChannel().call(new GetCharset()));
......@@ -225,7 +225,11 @@ public abstract class AbstractMavenProcessFactory
if ( mavenRemoteUseInet ) {
envVars.put(MAVEN_REMOTE_USEINET_ENV_VAR_NAME , "true" );
}
final ArgumentListBuilder cmdLine = buildMavenAgentCmdLine( listener,acceptor.getPort());
JDK jdk = getJava(listener);
JDK originalJdk = null;
JDK: while (true) {
final Acceptor acceptor = launcher.getChannel().call(new SocketHandler());
final ArgumentListBuilder cmdLine = buildMavenAgentCmdLine(listener, acceptor.getPort(), jdk);
String[] cmds = cmdLine.toCommandArray();
final Proc proc = launcher.launch().cmds(cmds).envs(envVars).stdout(mca).pwd(workDir).start();
......@@ -244,11 +248,27 @@ public abstract class AbstractMavenProcessFactory
Channel ch = Channels.forProcess("Channel to Maven " + Arrays.toString(cmds),
Computer.threadPoolForRemoting, new BufferedInputStream(con.in), new BufferedOutputStream(con.out),
listener.getLogger(), proc);
try {
ch.call(new ConfigureOriginalJDK(originalJdk));
} catch (IOException x) {
if (originalJdk == null) { // so we only try this once
for (Throwable t = x; t != null; t = t.getCause()) {
if (t instanceof UnsupportedClassVersionError) {
listener.error("[JENKINS-18403] JDK 5 not supported to run Maven; retrying with slave Java and setting compile/test properties to point to " + jdk.getHome());
originalJdk = jdk;
jdk = launcher.getChannel().call(new FindJavaHome());
continue JDK;
}
}
}
throw x;
}
if (!PlexusModuleContributorFactory.all().isEmpty())
applyPlexusModuleContributor(ch,build);
return new NewProcess(ch,proc);
}
} catch (IOException e) {
if(fixNull(e.getMessage()).contains("java: not found")) {
// diagnose issue #659
......@@ -260,6 +280,33 @@ public abstract class AbstractMavenProcessFactory
}
}
/** Verifies that the channel is open and functioning, and (if the second time around) sets properties for the original JDK. */
private static final class ConfigureOriginalJDK implements Callable<Void,Error> {
private static final long serialVersionUID = 1;
private final JDK jdk;
ConfigureOriginalJDK(JDK jdk) {
this.jdk = jdk;
}
@Override public Void call() throws Error {
if (jdk != null) {
System.setProperty("maven.compiler.fork", "true");
System.setProperty("maven.compiler.executable", new File(jdk.getBinDir(), File.separatorChar == '\\' ? "javac.exe" : "javac").getAbsolutePath());
// For Surefire, in case it is set to fork (we cannot unconditionally override forkMode):
System.setProperty("jvm", new File(jdk.getBinDir(), File.separatorChar == '\\' ? "java.exe" : "java").getAbsolutePath());
}
return null;
}
}
/** Locates JRE this slave agent is running on, or null. */
private static final class FindJavaHome implements Callable<JDK,Error> {
private static final long serialVersionUID = 1;
@Override public JDK call() throws Error {
JDK jdk = new JDK("this", System.getProperty("java.home"));
return jdk.getExists() ? jdk : /* i.e. just run "java" and hope for the best */null;
}
}
/**
* Apply extension plexus modules to the newly launched Maven process.
*
......@@ -276,6 +323,10 @@ public abstract class AbstractMavenProcessFactory
* Builds the command line argument list to launch the maven process.
*/
protected ArgumentListBuilder buildMavenAgentCmdLine(BuildListener listener,int tcpPort) throws IOException, InterruptedException {
return buildMavenAgentCmdLine(listener, tcpPort, getJava(listener));
}
private ArgumentListBuilder buildMavenAgentCmdLine(BuildListener listener, int tcpPort, JDK jdk) throws IOException, InterruptedException {
MavenInstallation mvn = getMavenInstallation(listener);
if(mvn==null) {
listener.error("Maven version is not configured for this project. Can't determine which Maven to run");
......@@ -292,7 +343,6 @@ public abstract class AbstractMavenProcessFactory
slaveRoot = getCurrentNode().getRootPath();
ArgumentListBuilder args = new ArgumentListBuilder();
JDK jdk = getJava(listener);
if(jdk==null) {
args.add("java");
} else {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册