Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
jglick committed Jul 17, 2013
1 parent 6fafc8c commit 288b8d0
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
3 changes: 3 additions & 0 deletions changelog.html
Expand Up @@ -61,6 +61,9 @@
<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>)
Expand Down
Expand Up @@ -29,6 +29,7 @@
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;
Expand Down Expand Up @@ -211,7 +212,6 @@ public ProcessCache.NewProcess newProcess(BuildListener listener, OutputStream o
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()));
Expand All @@ -225,7 +225,11 @@ public ProcessCache.NewProcess newProcess(BuildListener listener, OutputStream o
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();

Expand All @@ -244,11 +248,27 @@ public ProcessCache.NewProcess newProcess(BuildListener listener, OutputStream o
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());

This comment has been minimized.

Copy link
@daniel-beck

daniel-beck May 12, 2015

Member

It seems from JENKINS-28294 that this message needs to be updated for JDK 7.

Also, the reporter objects to this magic fallback mechanism. I wonder why this was added in the first place.

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
Expand All @@ -260,6 +280,33 @@ Computer.threadPoolForRemoting, new BufferedInputStream(con.in), new BufferedOut
}
}

/** 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.
*
Expand All @@ -276,6 +323,10 @@ Computer.threadPoolForRemoting, new BufferedInputStream(con.in), new BufferedOut
* 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");
Expand All @@ -292,7 +343,6 @@ protected ArgumentListBuilder buildMavenAgentCmdLine(BuildListener listener,int
slaveRoot = getCurrentNode().getRootPath();

ArgumentListBuilder args = new ArgumentListBuilder();
JDK jdk = getJava(listener);
if(jdk==null) {
args.add("java");
} else {
Expand Down

0 comments on commit 288b8d0

Please sign in to comment.