package org.jenkins.tools.test.maven;
import hudson.maven.MavenEmbedder;
import hudson.maven.MavenEmbedderException;
import hudson.maven.MavenRequest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.maven.execution.AbstractExecutionListener;
import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.MavenExecutionResult;
import org.codehaus.plexus.logging.Logger;
import org.jenkins.tools.test.exception.PomExecutionException;
import org.jenkins.tools.test.logging.SystemIOLoggerFilter;
public class InternalMavenRunner implements MavenRunner {
private MavenEmbedder embedder;
private void init(Config config) throws IOException, MavenEmbedderException {
if (embedder != null) {
return;
}
//here we don't care about paths for build the embedder
MavenRequest mavenRequest = buildMavenRequest(config, null, null);
embedder = new MavenEmbedder(Thread.currentThread().getContextClassLoader(), mavenRequest);
}
@Override public void run(Config config, File baseDirectory, File buildLogFile, String... goals) throws PomExecutionException {
try {
init(config);
} catch (Exception x) {
throw new PomExecutionException(x);
}
final List<String> succeededPlugins = new ArrayList<String>();
try {
MavenRequest mavenRequest = buildMavenRequest(config, baseDirectory.getAbsolutePath(),
config.userSettingsFile == null
? null
: config.userSettingsFile.getAbsolutePath());
mavenRequest.setGoals(Arrays.asList(goals));
mavenRequest.setPom(new File(baseDirectory, "pom.xml").getAbsolutePath());
AbstractExecutionListener mavenListener = new AbstractExecutionListener() {
@Override public void mojoSucceeded(ExecutionEvent event) {
succeededPlugins.add(event.getMojoExecution().getArtifactId());
}
};
mavenRequest.setExecutionListener(mavenListener);
mavenRequest.setLoggingLevel(Logger.LEVEL_INFO);
final PrintStream originalOut = System.out;
final PrintStream originalErr = System.err;
SystemIOLoggerFilter loggerFilter = new SystemIOLoggerFilter(buildLogFile);
// Since here, we are replacing System.out & System.err by
// wrappers logging things in the build log file
// We can't do this by using maven embedder's logger (or plexus logger)
// since :
// - It would imply to Instantiate a new MavenEmbedder for every test (which have a performance/memory cost !)
// - Plus it looks like there are lots of System.out/err.println() in maven
// plugin (instead of using maven logger)
System.setOut(new SystemIOLoggerFilter.SystemIOWrapper(loggerFilter, originalOut));
System.setErr(new SystemIOLoggerFilter.SystemIOWrapper(loggerFilter, originalErr));
try {
executeGoals(embedder, mavenRequest);
} catch (PomExecutionException x) {
PomExecutionException x2 = new PomExecutionException(x);
x2.succeededPluginArtifactIds.addAll(succeededPlugins);
throw x2;
} finally {
// Setting back System.out/err
System.setOut(originalOut);
System.setErr(originalErr);
}
} catch (IOException x) {
throw new PomExecutionException(x);
}
}
private static MavenRequest buildMavenRequest(Config config, String rootDir,String settingsPath)
throws IOException
{
MavenRequest mavenRequest = new MavenRequest();
mavenRequest.setBaseDirectory(rootDir);
mavenRequest.setUserSettingsFile(settingsPath);
mavenRequest.getUserProperties().putAll(config.userProperties);
return mavenRequest;
}
private static void executeGoals(MavenEmbedder mavenEmbedder, MavenRequest mavenRequest) throws PomExecutionException {
MavenExecutionResult result;
try {
result = mavenEmbedder.execute(mavenRequest);
}catch(MavenEmbedderException e){
// TODO: better manage this exception
throw new RuntimeException("Error during maven embedder execution", e);
}
if(!result.getExceptions().isEmpty()){
// If at least one OOME is thrown, rethrow it "as is"
// It must be treated a an internal error instead of a PomExecutionException !
for(Throwable t : result.getExceptions()){
if(t instanceof OutOfMemoryError){
throw (OutOfMemoryError)t;
}
}
throw new PomExecutionException("Error while executing pom goals : "+ mavenRequest.getGoals(), Collections.<String>emptyList(), result.getExceptions(), Collections.<String>emptyList());
}
}
}