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.
Originally-Committed-As: 288b8d0b01f92072d0b86efb898c011f31a7fc30
  • Loading branch information
jglick committed Jul 17, 2013
1 parent a9f64a8 commit 9bd5bae
Showing 1 changed file with 53 additions and 3 deletions.
56 changes: 53 additions & 3 deletions src/main/java/hudson/maven/AbstractMavenProcessFactory.java
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

This comment has been minimized.

Copy link
@kutzi

kutzi Oct 23, 2013

Member

As far as I can see getJava() as well as FindJavaHome can return null. So how can this ensure that it is only tried once - or even terminate at all?

This comment has been minimized.

Copy link
@jglick

jglick Oct 23, 2013

Author Member

Been three months, do not remember now.

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.

originalJdk = jdk;
jdk = launcher.getChannel().call(new FindJavaHome());
continue JDK;

This comment has been minimized.

Copy link
@kutzi

kutzi Oct 23, 2013

Member

continue with label? Really? What year is this? ;-)

This comment has been minimized.

Copy link
@jglick

jglick Oct 23, 2013

Author Member

Something wrong with continue with label?

This comment has been minimized.

Copy link
@kutzi

kutzi Oct 23, 2013

Member

Well I'd consider continue - with or without label - as not much better than a goto statement and therefore an antipattern in structured programming.
Obviously, this is opinional and there's nothing syntactical wrong with continues in Java

}
}
}
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 9bd5bae

Please sign in to comment.