Sorry my mistake.

This commit is contained in:
Seiji Sogabe 2010-12-24 22:19:10 +09:00
parent 535e9686bc
commit c85e60f14e
88 changed files with 4757 additions and 667 deletions

4
.gitignore vendored
View File

@ -6,11 +6,13 @@ work
*.iws
*.ipr
.idea
=======
# eclipse project file
.settings
.classpath
.project
build
war/images/16x16
war/images/24x24
@ -29,3 +31,5 @@ debian/configure-stamp
*.debhelper.log
hudson_*.build
hudson_*.changes
=======
push-build.sh

View File

@ -461,7 +461,6 @@ THE SOFTWARE.
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>

View File

@ -646,6 +646,13 @@ public abstract class PluginManager extends AbstractModelObject {
}
return Collections.enumeration(resources);
}
@Override
public String toString()
{
// only for debugging purpose
return "classLoader " + getClass().getName();
}
}
private static final Logger LOGGER = Logger.getLogger(PluginManager.class.getName());

View File

@ -362,6 +362,7 @@ public class Maven extends Builder {
*/
public static final int MAVEN_20 = 0;
public static final int MAVEN_21 = 1;
public static final int MAVEN_30 = 2;
/**
@ -405,6 +406,8 @@ public class Maven extends Builder {
* Represents the minimum required Maven version - constants defined above.
*/
public boolean meetsMavenReqVersion(Launcher launcher, int mavenReqVersion) throws IOException, InterruptedException {
// FIXME using similar stuff as in the maven plugin could be better
// olamy : but will add a dependency on maven in core -> so not so good
String mavenVersion = launcher.getChannel().call(new Callable<String,IOException>() {
public String call() throws IOException {
File[] jars = new File(getHomeDir(),"lib").listFiles();
@ -428,6 +431,10 @@ public class Maven extends Builder {
if(mavenVersion.startsWith("maven-2.") && !mavenVersion.startsWith("maven-2.0"))
return true;
}
else if (mavenReqVersion == MAVEN_30) {
if(mavenVersion.startsWith("maven-3.") && !mavenVersion.startsWith("maven-2.0"))
return true;
}
}
return false;

View File

@ -33,10 +33,10 @@ THE SOFTWARE.
<artifactId>maven-agent</artifactId>
<packaging>jar</packaging>
<name>Hudson Maven CLI agent</name>
<name>Hudson Maven2 CLI agent</name>
<description>
Code that boots up Maven2 with Hudson's remoting support in place.
Used for the native m2 support.
Used for the native maven support.
</description>
<build>
@ -73,12 +73,24 @@ THE SOFTWARE.
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>maven-interceptor</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-classworlds</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>classworlds</groupId>
<artifactId>classworlds</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
</dependency>
<dependency>
<!-- default dependency to 2.0.2 confuses IntelliJ. Otherwise this value doesn't really affect build or runtime. -->
<groupId>commons-httpclient</groupId>
@ -90,8 +102,14 @@ THE SOFTWARE.
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${maven.version}</version>
<scope>test</scope>
<version>2.0.9</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>classworlds</groupId>
<artifactId>classworlds</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jvnet.hudson.main</groupId>

View File

@ -23,25 +23,25 @@
*/
package hudson.maven.agent;
import org.codehaus.classworlds.ClassRealm;
import org.codehaus.classworlds.ClassWorld;
import org.codehaus.classworlds.DefaultClassRealm;
import org.codehaus.classworlds.Launcher;
import org.codehaus.classworlds.NoSuchRealmException;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.codehaus.classworlds.ClassRealm;
import org.codehaus.classworlds.ClassWorld;
import org.codehaus.classworlds.DefaultClassRealm;
import org.codehaus.classworlds.Launcher;
import org.codehaus.classworlds.NoSuchRealmException;
/**
* Entry point for launching Maven and Hudson remoting in the same VM,
* in the classloader layout that Maven expects.
@ -110,9 +110,14 @@ public class Main {
// have it eventually delegate to this class so that this can be visible
//ClassWorldAdapter classWorldAdapter = ClassWorldAdapter.getInstance( launcher.getWorld() );
// create a realm for loading remoting subsystem.
// this needs to be able to see maven.
//ClassRealm remoting = new DefaultClassRealm(classWorldAdapter,"hudson-remoting", launcher.getSystemClassLoader());
ClassRealm remoting = new DefaultClassRealm(launcher.getWorld(),"hudson-remoting", launcher.getSystemClassLoader());
remoting.setParent(launcher.getWorld().getRealm("plexus.core.maven"));
remoting.addConstituent(remotingJar.toURI().toURL());
@ -156,10 +161,13 @@ public class Main {
/**
* Called by the code in remoting to launch.
* @throws org.codehaus.plexus.classworlds.realm.NoSuchRealmException
*/
public static int launch(String[] args) throws NoSuchMethodException, IllegalAccessException, NoSuchRealmException, InvocationTargetException, ClassNotFoundException {
ClassWorld world = launcher.getWorld();
//ClassWorld world = ClassWorldAdapter.getInstance( launcher.getWorld() );
ClassWorld world = launcher.getWorld();
Set builtinRealms = new HashSet(world.getRealms());
try {
launcher.launch(args);
@ -178,4 +186,4 @@ public class Main {
}
return launcher.getExitCode();
}
}
}

View File

@ -10,4 +10,4 @@ load ${maven.interceptor.override}
load ${maven.interceptor}
load ${maven.home}/lib/*.jar
[plexus.core.maven]
[plexus.core.maven]

View File

@ -33,7 +33,7 @@ THE SOFTWARE.
<artifactId>maven-interceptor</artifactId>
<packaging>jar</packaging>
<name>Hudson Maven PluginManager interceptor</name>
<name>Hudson Maven 2 PluginManager interceptor</name>
<description>
Plexus module that intercepts invocations of key Maven components
so that Hudson can monitor what's going on in Maven.
@ -43,9 +43,17 @@ THE SOFTWARE.
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${maven.version}</version>
<version>2.0.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>classworlds</groupId>
<artifactId>classworlds</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<!-- default dependency to 2.0.2 confuses IntelliJ. Otherwise this value doesn't really affect build or runtime. -->
<groupId>commons-httpclient</groupId>

View File

@ -23,16 +23,19 @@
*/
package hudson.maven.agent;
import java.io.IOException;
import java.lang.reflect.Method;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.DefaultPluginManager;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.PluginConfigurationException;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.reporting.MavenReport;
@ -43,13 +46,10 @@ import org.codehaus.plexus.component.configurator.ComponentConfigurationExceptio
import org.codehaus.plexus.component.configurator.ComponentConfigurator;
import org.codehaus.plexus.component.configurator.ConfigurationListener;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* Description in META-INF/plexus/components.xml makes it possible to use this instead of the default
* plugin manager.

View File

@ -37,165 +37,308 @@ THE SOFTWARE.
Now it is a plug-in that is installed by default, but can be disabled.</description>
<url>http://wiki.hudson-ci.org/display/HUDSON/Maven+2+Project+Plugin</url>
<dependencies>
<dependency>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>hudson-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependencies>
<dependency>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>hudson-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>maven-agent</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>classworlds</groupId>
<artifactId>classworlds</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>maven-interceptor</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>classworlds</groupId>
<artifactId>classworlds</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>maven2.1-interceptor</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>maven3-agent</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>maven3-interceptor</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-api</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-impl</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-spi</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-util</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-connector-wagon</artifactId>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-http-lightweight</artifactId>
<exclusions>
<exclusion>
<groupId>nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</exclusion>
<exclusion>
<groupId>nekohtml</groupId>
<artifactId>xercesMinimal</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-file</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>${wagonVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>${wagonVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh-external</artifactId>
<version>${wagonVersion}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>maven-agent</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>maven2.1-interceptor</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>maven-embedder</artifactId>
<version>2.0.4-hudson-1</version>
<!--exclusions> These are needed for Maven embedder to resolve parent POMs in remote repositories
<exclusion>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-file</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-http-lightweight</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh-external</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
</exclusion>
</exclusions-->
<exclusions>
<exclusion><!-- we'll add our own patched version. see http://www.nabble.com/Issue-1680-td18383889.html -->
<groupId>jtidy</groupId>
<artifactId>jtidy</artifactId>
</exclusion>
<exclusion>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</exclusion>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<!-- we bundle our own version below -->
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-webdav</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<!-- commonly used wagon provider -->
<groupId>org.jvnet.hudson</groupId>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-provider-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.reporting</groupId>
<artifactId>maven-reporting-api</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-classworlds</artifactId>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>hudson-maven-artifact-manager</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.jvnet.hudson</groupId>
<artifactId>hudson-maven-embedder</artifactId>
<version>3.0</version>
<exclusions>
<exclusion><!-- we'll add our own patched version. see http://www.nabble.com/Issue-1680-td18383889.html -->
<groupId>jtidy</groupId>
<artifactId>jtidy</artifactId>
</exclusion>
<exclusion>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</exclusion>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<!-- we bundle our own version below -->
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-webdav</artifactId>
<version>1.0-beta-2-hudson-1</version>
<exclusions>
<exclusion>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</exclusion>
<build>
<!--
Since new versions need to overwrite old versions, it's better
not to have version number in the .hpi file name.
-->
<finalName>${project.artifactId}</finalName>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.jvnet.hudson.tools</groupId>
<artifactId>maven-hpi-plugin</artifactId>
<version>1.54</version>
<extensions>true</extensions>
<configuration>
<showDeprecation>true</showDeprecation>
<disabledTestInjection>true</disabledTestInjection>
</configuration>
</plugin>
<plugin>
<groupId>org.kohsuke.stapler</groupId>
<artifactId>maven-stapler-plugin</artifactId>
<version>1.12</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.jvnet.localizer</groupId>
<artifactId>maven-localizer-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<fileMask>Messages.properties</fileMask>
<outputDirectory>target/generated-sources/localizer</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cobertura2</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.4-apb-SNAPSHOT</version>
<inherited>true</inherited>
<!-- prefer net.sourceforge.nekohtml:nekohtml:jar:1.9.13 so that we use consistent version across Hudson -->
<exclusion>
<groupId>nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</exclusion>
<exclusion>
<groupId>nekohtml</groupId>
<artifactId>xercesMinimal</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<!-- commonly used wagon provider -->
<groupId>org.jvnet.hudson</groupId>
<artifactId>wagon-webdav</artifactId>
<version>1.0-beta-2-hudson-1</version>
<exclusions>
<exclusion>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.13</version>
</dependency>
</dependencies>
<build>
<!--
Since new versions need to overwrite old versions, it's better
not to have version number in the .hpi file name.
-->
<finalName>${project.artifactId}</finalName>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.jvnet.hudson.tools</groupId>
<artifactId>maven-hpi-plugin</artifactId>
<version>1.54</version>
<extensions>true</extensions>
<configuration>
<showDeprecation>true</showDeprecation>
<disabledTestInjection>true</disabledTestInjection>
</configuration>
</plugin>
<plugin>
<groupId>org.kohsuke.stapler</groupId>
<artifactId>maven-stapler-plugin</artifactId>
<version>1.12</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.jvnet.localizer</groupId>
<artifactId>maven-localizer-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
<fileMask>Messages.properties</fileMask>
<outputDirectory>target/generated-sources/localizer</outputDirectory>
</configuration>
<executions>
<execution>
<id>coverage-instrument</id>
<phase>process-test-classes</phase>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>coverage-report</id>
<phase>test</phase>
<goals>
<goal>generate-report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jvnet.maven-antrun-extended-plugin</groupId>
<artifactId>maven-antrun-extended-plugin</artifactId>
<executions>
<execution>
<id>resgen</id>
<phase>generate-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<verifyArtifact>false</verifyArtifact>
<tasks>
<mkdir dir="target/classes" />
<!-- classworld 1.1 for maven 2 builds -->
<resolveArtifact groupId="classworlds" artifactId="classworlds" version="1.1" type="jar" tofile="target/classes/classworlds.jar" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>cobertura2</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.4-apb-SNAPSHOT</version>
<inherited>true</inherited>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
</configuration>
<executions>
<execution>
<id>coverage-instrument</id>
<phase>process-test-classes</phase>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>coverage-report</id>
<phase>test</phase>
<goals>
<goal>generate-report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,88 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Olivier Lamy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.maven;
import hudson.model.BuildListener;
import hudson.model.Hudson;
import hudson.model.Result;
import hudson.remoting.DelegatingCallable;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
/**
* @author Olivier Lamy
*
*/
public abstract class AbstractMavenBuilder implements DelegatingCallable<Result,IOException> {
/**
* Goals to be executed in this Maven execution.
*/
protected final List<String> goals;
/**
* Hudson-defined system properties. These will be made available to Maven,
* and accessible as if they are specified as -Dkey=value
*/
protected final Map<String,String> systemProps;
/**
* Where error messages and so on are sent.
*/
protected final BuildListener listener;
protected AbstractMavenBuilder(BuildListener listener, List<String> goals, Map<String, String> systemProps) {
this.listener = listener;
this.goals = goals;
this.systemProps = systemProps;
}
protected String formatArgs(List<String> args) {
StringBuilder buf = new StringBuilder("Executing Maven: ");
for (String arg : args) {
final String argPassword = "-Dpassword=" ;
String filteredArg = arg ;
// check if current arg is password arg. Then replace password by *****
if (arg.startsWith(argPassword)) {
filteredArg=argPassword+"*********";
}
buf.append(' ').append(filteredArg);
}
return buf.toString();
}
protected String format(NumberFormat n, long nanoTime) {
return n.format(nanoTime/1000000);
}
// since reporters might be from plugins, use the uberjar to resolve them.
public ClassLoader getClassLoader() {
return Hudson.getInstance().getPluginManager().uberClassLoader;
}
}

View File

@ -24,22 +24,25 @@
package hudson.maven;
import hudson.model.TaskListener;
import org.apache.maven.embedder.AbstractMavenEmbedderLogger;
import org.apache.maven.embedder.MavenEmbedderLogger;
import java.io.PrintStream;
import java.util.StringTokenizer;
import org.apache.maven.cli.MavenLoggerManager;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
/**
* {@link MavenEmbedderLogger} implementation that
* sends output to {@link TaskListener}.
*
* @author Kohsuke Kawaguchi
*/
public final class EmbedderLoggerImpl extends AbstractMavenEmbedderLogger {
public final class EmbedderLoggerImpl extends MavenLoggerManager {
private final PrintStream logger;
public EmbedderLoggerImpl(TaskListener listener) {
public EmbedderLoggerImpl(TaskListener listener, int threshold) {
super(new ConsoleLogger( threshold, "hudson-logger" ));
logger = listener.getLogger();
}
@ -57,22 +60,22 @@ public final class EmbedderLoggerImpl extends AbstractMavenEmbedderLogger {
}
public void debug(String message, Throwable throwable) {
print(message, throwable, LEVEL_DEBUG, "[DEBUG] ");
print(message, throwable, Logger.LEVEL_DEBUG, "[DEBUG] ");
}
public void info(String message, Throwable throwable) {
print(message, throwable, LEVEL_INFO, "[INFO ] ");
print(message, throwable, Logger.LEVEL_INFO, "[INFO ] ");
}
public void warn(String message, Throwable throwable) {
print(message, throwable, LEVEL_WARN, "[WARN ] ");
print(message, throwable, Logger.LEVEL_WARN, "[WARN ] ");
}
public void error(String message, Throwable throwable) {
print(message, throwable, LEVEL_ERROR, "[ERROR] ");
print(message, throwable, Logger.LEVEL_ERROR, "[ERROR] ");
}
public void fatalError(String message, Throwable throwable) {
print(message, throwable, LEVEL_FATAL, "[FATAL] ");
print(message, throwable, Logger.LEVEL_FATAL, "[FATAL] ");
}
}

View File

@ -23,22 +23,24 @@
*/
package hudson.maven;
import static hudson.Util.intern;
import hudson.Util;
import hudson.model.Hudson;
import hudson.remoting.Which;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.kohsuke.stapler.Stapler;
import hudson.util.ReflectionUtils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.logging.Logger;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static hudson.Util.intern;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.kohsuke.stapler.Stapler;
/**
* Persisted record of mojo execution.
@ -80,7 +82,7 @@ public final class ExecutedMojo implements Serializable {
*/
public final String digest;
ExecutedMojo(MojoInfo mojo, long duration) throws IOException, InterruptedException {
public ExecutedMojo(MojoInfo mojo, long duration) throws IOException, InterruptedException {
this.groupId = mojo.pluginName.groupId;
this.artifactId = mojo.pluginName.artifactId;
this.version = mojo.pluginName.version;
@ -92,7 +94,7 @@ public final class ExecutedMojo implements Serializable {
MojoDescriptor md = mojo.mojoExecution.getMojoDescriptor();
PluginDescriptor pd = md.getPluginDescriptor();
try {
Class clazz = pd.getClassRealm().loadClass(md.getImplementation());
Class clazz = getMojoClass( md, pd );// pd.getClassRealm().loadClass(md.getImplementation());
digest = Util.getDigestOf(new FileInputStream(Which.jarFile(clazz)));
} catch (IllegalArgumentException e) {
LOGGER.log(Level.WARNING, "Failed to locate jar for "+md.getImplementation(),e);
@ -101,6 +103,28 @@ public final class ExecutedMojo implements Serializable {
}
this.digest = digest;
}
private Class<?> getMojoClass(MojoDescriptor md, PluginDescriptor pd) throws ClassNotFoundException {
try {
return pd.getClassRealm().loadClass( md.getImplementation() );
} catch (NoSuchMethodError e) {
// maybe we are in maven2 build ClassRealm package has changed
return getMojoClassForMaven2( md, pd );
}
}
private Class<?> getMojoClassForMaven2(MojoDescriptor md, PluginDescriptor pd) throws ClassNotFoundException {
Method method = ReflectionUtils.getPublicMethodNamed( pd.getClass(), "getClassRealm" );
org.codehaus.classworlds.ClassRealm cl =
(org.codehaus.classworlds.ClassRealm) ReflectionUtils.invokeMethod( method, pd );
Class<?> clazz = cl.loadClass( md.getImplementation() );
return clazz;
}
/**
* Copy constructor used for interning.

View File

@ -0,0 +1,680 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Olivier Lamy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.maven;
import hudson.Launcher;
import hudson.maven.MavenBuild.ProxyImpl2;
import hudson.model.BuildListener;
import hudson.model.Hudson;
import hudson.model.Result;
import hudson.remoting.Channel;
import hudson.remoting.DelegatingCallable;
import hudson.remoting.Future;
import hudson.util.IOException2;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import org.apache.maven.execution.AbstractExecutionListener;
import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.ExecutionListener;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.jvnet.hudson.maven3.agent.Maven3Main;
import org.jvnet.hudson.maven3.launcher.Maven3Launcher;
import org.jvnet.hudson.maven3.listeners.HudsonMavenExecutionResult;
/**
* @author Olivier Lamy
*
*/
public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCallable<Result,IOException> {
/**
* Flag needs to be set at the constructor, so that this reflects
* the setting at master.
*/
private final boolean profile = MavenProcessFactory.profile;
/**
* Record all asynchronous executions as they are scheduled,
* to make sure they are all completed before we finish.
*/
protected transient /*final*/ List<Future<?>> futures;
HudsonMavenExecutionResult mavenExecutionResult;
private final Map<ModuleName,MavenBuildProxy2> proxies;
private final Map<ModuleName,ProxyImpl2> sourceProxies;
private final Map<ModuleName,List<MavenReporter>> reporters = new HashMap<ModuleName,List<MavenReporter>>();
protected Maven3Builder(BuildListener listener,Map<ModuleName,ProxyImpl2> proxies, Map<ModuleName,List<MavenReporter>> reporters, List<String> goals, Map<String, String> systemProps) {
super( listener, goals, systemProps );
sourceProxies = new HashMap<ModuleName, ProxyImpl2>(proxies);
this.proxies = new HashMap<ModuleName, MavenBuildProxy2>(proxies);
for (Entry<ModuleName,MavenBuildProxy2> e : this.proxies.entrySet())
e.setValue(new FilterImpl(e.getValue()));
this.reporters.putAll( reporters );
}
public Result call() throws IOException {
MavenExecutionListener mavenExecutionListener = new MavenExecutionListener( this );
try {
futures = new ArrayList<Future<?>>();
Maven3Launcher.setMavenExecutionListener( mavenExecutionListener );
markAsSuccess = false;
// working around NPE when someone puts a null value into systemProps.
for (Map.Entry<String,String> e : systemProps.entrySet()) {
if (e.getValue()==null)
throw new IllegalArgumentException("System property "+e.getKey()+" has a null value");
System.getProperties().put(e.getKey(), e.getValue());
}
listener.getLogger().println(formatArgs(goals));
int r = Maven3Main.launch( goals.toArray(new String[goals.size()]));
// now check the completion status of async ops
boolean messageReported = false;
long startTime = System.nanoTime();
for (Future<?> f : futures) {
try {
if(!f.isDone() && !messageReported) {
messageReported = true;
// FIXME messages
listener.getLogger().println("maven builder waiting");
}
f.get();
} catch (InterruptedException e) {
// attempt to cancel all asynchronous tasks
for (Future<?> g : futures)
g.cancel(true);
// FIXME messages
listener.getLogger().println("build aborted");
return Result.ABORTED;
} catch (ExecutionException e) {
// FIXME messages
e.printStackTrace(listener.error("async build failed"));
}
}
mavenExecutionListener.overheadTime += System.nanoTime()-startTime;
futures.clear();
if(profile) {
NumberFormat n = NumberFormat.getInstance();
PrintStream logger = listener.getLogger();
logger.println("Total overhead was "+format(n,mavenExecutionListener.overheadTime)+"ms");
Channel ch = Channel.current();
logger.println("Class loading " +format(n,ch.classLoadingTime.get()) +"ms, "+ch.classLoadingCount+" classes");
logger.println("Resource loading "+format(n,ch.resourceLoadingTime.get())+"ms, "+ch.resourceLoadingCount+" times");
}
mavenExecutionResult = Maven3Launcher.getMavenExecutionResult();
PrintStream logger = listener.getLogger();
if(r==0 && mavenExecutionResult.getThrowables().isEmpty()) return Result.SUCCESS;
if (!mavenExecutionResult.getThrowables().isEmpty()) {
logger.println( "mavenExecutionResult exceptions not empty");
for(Throwable throwable : mavenExecutionResult.getThrowables()) {
throwable.printStackTrace( logger );
}
}
if(markAsSuccess) {
listener.getLogger().println(Messages.MavenBuilder_Failed());
return Result.SUCCESS;
}
return Result.FAILURE;
} catch (NoSuchMethodException e) {
throw new IOException2(e);
} catch (IllegalAccessException e) {
throw new IOException2(e);
} catch (InvocationTargetException e) {
throw new IOException2(e);
} catch (ClassNotFoundException e) {
throw new IOException2(e);
} catch (Exception e) {
throw new IOException2(e);
}
}
// since reporters might be from plugins, use the uberjar to resolve them.
public ClassLoader getClassLoader() {
return Hudson.getInstance().getPluginManager().uberClassLoader;
}
/**
* Invoked after the maven has finished running, and in the master, not in the maven process.
*/
void end(Launcher launcher) throws IOException, InterruptedException {
for (Map.Entry<ModuleName,ProxyImpl2> e : sourceProxies.entrySet()) {
ProxyImpl2 p = e.getValue();
for (MavenReporter r : reporters.get(e.getKey())) {
// we'd love to do this when the module build ends, but doing so requires
// we know how many task segments are in the current build.
r.end(p.owner(),launcher,listener);
p.appendLastLog();
}
p.close();
}
}
private class FilterImpl extends MavenBuildProxy2.Filter<MavenBuildProxy2> implements Serializable {
public FilterImpl(MavenBuildProxy2 core) {
super(core);
}
@Override
public void executeAsync(final BuildCallable<?,?> program) throws IOException {
futures.add(Channel.current().callAsync(new AsyncInvoker(core,program)));
}
private static final long serialVersionUID = 1L;
}
private static final class MavenExecutionListener extends AbstractExecutionListener implements Serializable, ExecutionListener {
private final Maven3Builder maven3Builder;
/**
* Number of total nanoseconds {@link Maven3Builder} spent.
*/
long overheadTime;
private final Map<ModuleName,MavenBuildProxy2> proxies;
private final Map<ModuleName,List<ExecutedMojo>> executedMojosPerModule = new ConcurrentHashMap<ModuleName, List<ExecutedMojo>>();
private final Map<ModuleName,List<MavenReporter>> reporters = new HashMap<ModuleName,List<MavenReporter>>();
private final Map<ModuleName, Long> currentMojoStartPerModuleName = new ConcurrentHashMap<ModuleName, Long>();
public MavenExecutionListener(Maven3Builder maven3Builder) {
this.maven3Builder = maven3Builder;
this.proxies = new HashMap<ModuleName, MavenBuildProxy2>(maven3Builder.proxies);
for (Entry<ModuleName,MavenBuildProxy2> e : this.proxies.entrySet())
{
e.setValue(maven3Builder.new FilterImpl(e.getValue()));
executedMojosPerModule.put( e.getKey(), new CopyOnWriteArrayList<ExecutedMojo>() );
}
this.reporters.putAll( new HashMap<ModuleName, List<MavenReporter>>(maven3Builder.reporters) );
}
private MavenBuildProxy2 getMavenBuildProxy2(MavenProject mavenProject) {
for (Entry<ModuleName,MavenBuildProxy2> entry : proxies.entrySet()) {
if (entry.getKey().compareTo( new ModuleName( mavenProject ) ) == 0) {
return entry.getValue();
}
}
return null;
}
// FIME really used somewhere ???
// FIXME MojoInfo need the real mojo ??
// so tricky to do. need to use MavenPluginManager on the current Maven Build
private Mojo getMojo(MojoExecution mojoExecution, MavenSession mavenSession) {
return null;
}
private ExpressionEvaluator getExpressionEvaluator(MavenSession session, MojoExecution mojoExecution) {
return new PluginParameterExpressionEvaluator( session, mojoExecution );
}
private List<MavenReporter> getMavenReporters(MavenProject mavenProject) {
return reporters.get( new ModuleName( mavenProject ) );
}
private void initMojoStartTime( MavenProject mavenProject) {
this.currentMojoStartPerModuleName.put( new ModuleName( mavenProject.getGroupId(),
mavenProject.getArtifactId() ),
Long.valueOf( new Date().getTime() ) );
}
private Long getMojoStartTime(MavenProject mavenProject) {
return currentMojoStartPerModuleName.get( new ModuleName( mavenProject.getGroupId(),
mavenProject.getArtifactId() ) );
}
/**
* @see org.apache.maven.execution.ExecutionListener#projectDiscoveryStarted(org.apache.maven.execution.ExecutionEvent)
*/
public void projectDiscoveryStarted( ExecutionEvent event ) {
// no op
}
/**
* @see org.apache.maven.execution.ExecutionListener#sessionStarted(org.apache.maven.execution.ExecutionEvent)
*/
public void sessionStarted( ExecutionEvent event ) {
// no op
}
/**
* @see org.apache.maven.execution.ExecutionListener#sessionEnded(org.apache.maven.execution.ExecutionEvent)
*/
public void sessionEnded( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println( "sessionEnded" );
}
/**
* @see org.apache.maven.execution.ExecutionListener#projectSkipped(org.apache.maven.execution.ExecutionEvent)
*/
public void projectSkipped( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("projectSkipped " + event.getProject().getGroupId()
+ ":" + event.getProject().getArtifactId()
+ ":" + event.getProject().getVersion());
}
/**
* @see org.apache.maven.execution.ExecutionListener#projectStarted(org.apache.maven.execution.ExecutionEvent)
*/
public void projectStarted( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println( "projectStarted " + event.getProject().getGroupId() + ":"
+ event.getProject().getArtifactId() + ":" + event.getProject().getVersion() );
reccordProjectStarted( event );
}
public void reccordProjectStarted( ExecutionEvent event ) {
MavenProject mavenProject = event.getProject();
List<MavenReporter> mavenReporters = getMavenReporters( mavenProject );
MavenBuildProxy2 mavenBuildProxy2 = getMavenBuildProxy2( mavenProject );
mavenBuildProxy2.start();
if (mavenReporters != null) {
for (MavenReporter mavenReporter : mavenReporters) {
try {
mavenReporter.enterModule( mavenBuildProxy2 ,mavenProject, maven3Builder.listener);
} catch ( InterruptedException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
if (mavenReporters != null) {
for (MavenReporter mavenReporter : mavenReporters) {
try {
mavenReporter.preBuild( mavenBuildProxy2 ,mavenProject, maven3Builder.listener);
} catch ( InterruptedException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
/**
* @see org.apache.maven.execution.ExecutionListener#projectSucceeded(org.apache.maven.execution.ExecutionEvent)
*/
public void projectSucceeded( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println( "projectSucceeded "
+ event.getProject().getGroupId() + ":"
+ event.getProject().getArtifactId() + ":"
+ event.getProject().getVersion());
reccordProjectSucceeded( event );
}
public void reccordProjectSucceeded( ExecutionEvent event ) {
MavenBuildProxy2 mavenBuildProxy2 = getMavenBuildProxy2( event.getProject() );
mavenBuildProxy2.end();
mavenBuildProxy2.setResult( Result.SUCCESS );
List<MavenReporter> mavenReporters = getMavenReporters( event.getProject() );
if ( mavenReporters != null ) {
for ( MavenReporter mavenReporter : mavenReporters ) {
try {
mavenReporter.leaveModule( mavenBuildProxy2, event.getProject(), maven3Builder.listener);
} catch ( InterruptedException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
if ( mavenReporters != null ) {
for ( MavenReporter mavenReporter : mavenReporters ) {
try {
mavenReporter.postBuild( mavenBuildProxy2, event.getProject(), maven3Builder.listener);
} catch ( InterruptedException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
/**
* @see org.apache.maven.execution.ExecutionListener#projectFailed(org.apache.maven.execution.ExecutionEvent)
*/
public void projectFailed( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("projectFailed " + event.getProject().getGroupId()
+ ":" + event.getProject().getArtifactId()
+ ":" + event.getProject().getVersion());
reccordProjectFailed( event );
}
public void reccordProjectFailed( ExecutionEvent event ) {
MavenBuildProxy2 mavenBuildProxy2 = getMavenBuildProxy2( event.getProject() );
mavenBuildProxy2.end();
mavenBuildProxy2.setResult( Result.FAILURE );
MavenProject mavenProject = event.getProject();
List<MavenReporter> mavenReporters = getMavenReporters( mavenProject );
if ( mavenReporters != null ) {
for ( MavenReporter mavenReporter : mavenReporters ) {
try {
mavenReporter.leaveModule( mavenBuildProxy2, mavenProject, maven3Builder.listener);
} catch ( InterruptedException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
if ( mavenReporters != null ) {
for ( MavenReporter mavenReporter : mavenReporters ) {
try {
mavenReporter.postBuild( mavenBuildProxy2, mavenProject, maven3Builder.listener);
} catch ( InterruptedException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
/**
* @see org.apache.maven.execution.ExecutionListener#mojoSkipped(org.apache.maven.execution.ExecutionEvent)
*/
public void mojoSkipped( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("mojoSkipped " + event.getMojoExecution().getGroupId() + ":"
+ event.getMojoExecution().getArtifactId() + ":"
+ event.getMojoExecution().getVersion()
+ "(" + event.getMojoExecution().getExecutionId() + ")");
}
/**
* @see org.apache.maven.execution.ExecutionListener#mojoStarted(org.apache.maven.execution.ExecutionEvent)
*/
public void mojoStarted( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("mojoStarted " + event.getMojoExecution().getGroupId() + ":"
+ event.getMojoExecution().getArtifactId() + ":"
+ event.getMojoExecution().getVersion()
+ "(" + event.getMojoExecution().getExecutionId() + ")");
reccordMojoStarted( event );
}
public void reccordMojoStarted( ExecutionEvent event ) {
initMojoStartTime( event.getProject() );
MavenProject mavenProject = event.getProject();
XmlPlexusConfiguration xmlPlexusConfiguration = new XmlPlexusConfiguration( event.getMojoExecution().getConfiguration() );
Mojo mojo = null;//getMojo( event.getMojoExecution(), event.getSession() );
MojoInfo mojoInfo =
new MojoInfo( event.getMojoExecution(), mojo, xmlPlexusConfiguration,
getExpressionEvaluator( event.getSession(), event.getMojoExecution() ) );
List<MavenReporter> mavenReporters = getMavenReporters( mavenProject );
MavenBuildProxy2 mavenBuildProxy2 = getMavenBuildProxy2( mavenProject );
if (mavenReporters != null) {
for (MavenReporter mavenReporter : mavenReporters) {
try {
mavenReporter.preExecute( mavenBuildProxy2, mavenProject, mojoInfo, maven3Builder.listener);
} catch ( InterruptedException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
/**
* @see org.apache.maven.execution.ExecutionListener#mojoSucceeded(org.apache.maven.execution.ExecutionEvent)
*/
public void mojoSucceeded( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("mojoSucceeded " + event.getMojoExecution().getGroupId() + ":"
+ event.getMojoExecution().getArtifactId() + ":"
+ event.getMojoExecution().getVersion()
+ "(" + event.getMojoExecution().getExecutionId() + ")");
reccordMojoSucceeded( event );
}
public void reccordMojoSucceeded( ExecutionEvent event ) {
Long startTime = getMojoStartTime( event.getProject() );
Date endTime = new Date();
MavenProject mavenProject = event.getProject();
XmlPlexusConfiguration xmlPlexusConfiguration = new XmlPlexusConfiguration( event.getMojoExecution().getConfiguration() );
Mojo mojo = null;//getMojo( event.getMojoExecution(), event.getSession() );
MojoInfo mojoInfo =
new MojoInfo( event.getMojoExecution(), mojo, xmlPlexusConfiguration,
getExpressionEvaluator( event.getSession(), event.getMojoExecution() ) );
try {
ExecutedMojo executedMojo =
new ExecutedMojo( mojoInfo, startTime == null ? 0 : endTime.getTime() - startTime.longValue() );
this.executedMojosPerModule.get( new ModuleName( mavenProject.getGroupId(),
mavenProject.getArtifactId() ) ).add( executedMojo );
} catch ( Exception e ) {
// ignoring this
maven3Builder.listener.getLogger().println( "ignoring exception during new ExecutedMojo "
+ e.getMessage() );
}
List<MavenReporter> mavenReporters = getMavenReporters( mavenProject );
MavenBuildProxy2 mavenBuildProxy2 = getMavenBuildProxy2( mavenProject );
mavenBuildProxy2.setExecutedMojos( this.executedMojosPerModule.get( new ModuleName( event.getProject() ) ) );
if (mavenReporters != null) {
for (MavenReporter mavenReporter : mavenReporters) {
try {
mavenReporter.postExecute( mavenBuildProxy2, mavenProject, mojoInfo, maven3Builder.listener, null);
} catch ( InterruptedException e ) {
e.printStackTrace();
}
catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
/**
* @see org.apache.maven.execution.ExecutionListener#mojoFailed(org.apache.maven.execution.ExecutionEvent)
*/
public void mojoFailed( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("mojoFailed " + event.getMojoExecution().getGroupId() + ":"
+ event.getMojoExecution().getArtifactId() + ":"
+ event.getMojoExecution().getVersion()
+ "(" + event.getMojoExecution().getExecutionId() + ")");
reccordMojoFailed( event );
}
public void reccordMojoFailed( ExecutionEvent event ) {
Long startTime = getMojoStartTime( event.getProject() );
Date endTime = new Date();
MavenProject mavenProject = event.getProject();
XmlPlexusConfiguration xmlPlexusConfiguration = new XmlPlexusConfiguration( event.getMojoExecution().getConfiguration() );
Mojo mojo = null;//getMojo( event.getMojoExecution(), event.getSession() );
MojoInfo mojoInfo =
new MojoInfo( event.getMojoExecution(), mojo, xmlPlexusConfiguration,
getExpressionEvaluator( event.getSession(), event.getMojoExecution() ) );
try {
ExecutedMojo executedMojo =
new ExecutedMojo( mojoInfo, startTime == null ? 0 : endTime.getTime() - startTime.longValue() );
this.executedMojosPerModule.get( new ModuleName( mavenProject.getGroupId(),
mavenProject.getArtifactId() ) ).add( executedMojo );
} catch ( Exception e ) {
// ignoring this
maven3Builder.listener.getLogger().println( "ignoring exception during new ExecutedMojo "
+ e.getMessage() );
}
List<MavenReporter> mavenReporters = getMavenReporters( mavenProject );
MavenBuildProxy2 mavenBuildProxy2 = getMavenBuildProxy2( mavenProject );
mavenBuildProxy2.setExecutedMojos( this.executedMojosPerModule.get( new ModuleName( event.getProject() ) ) );
if (mavenReporters != null) {
for (MavenReporter mavenReporter : mavenReporters) {
try {
// TODO get exception during mojo execution ?
// with maven 3.0.2 see http://jira.codehaus.org/browse/MNG-4922
// catch NoSuchMethodError if folks not using 3.0.2+
mavenReporter.postExecute( mavenBuildProxy2, mavenProject, mojoInfo, maven3Builder.listener, null );
} catch ( InterruptedException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
/**
* @see org.apache.maven.execution.ExecutionListener#forkStarted(org.apache.maven.execution.ExecutionEvent)
*/
public void forkStarted( ExecutionEvent event )
{
maven3Builder.listener.getLogger().println("mojo forkStarted " + event.getMojoExecution().getGroupId() + ":"
+ event.getMojoExecution().getArtifactId() + ":"
+ event.getMojoExecution().getVersion()
+ "(" + event.getMojoExecution().getExecutionId() + ")");
reccordMojoStarted( event );
}
/**
* @see org.apache.maven.execution.ExecutionListener#forkSucceeded(org.apache.maven.execution.ExecutionEvent)
*/
public void forkSucceeded( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("mojo forkSucceeded " + event.getMojoExecution().getGroupId() + ":"
+ event.getMojoExecution().getArtifactId() + ":"
+ event.getMojoExecution().getVersion()
+ "(" + event.getMojoExecution().getExecutionId() + ")");
reccordMojoSucceeded( event );
}
/**
* @see org.apache.maven.execution.ExecutionListener#forkFailed(org.apache.maven.execution.ExecutionEvent)
*/
public void forkFailed( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("mojo forkFailed " + event.getMojoExecution().getGroupId() + ":"
+ event.getMojoExecution().getArtifactId() + ":"
+ event.getMojoExecution().getVersion()
+ "(" + event.getMojoExecution().getExecutionId() + ")");
reccordMojoFailed( event );
}
/**
* @see org.apache.maven.execution.ExecutionListener#forkedProjectStarted(org.apache.maven.execution.ExecutionEvent)
*/
public void forkedProjectStarted( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println( "forkedProjectStarted " + event.getProject().getGroupId() + ":"
+ event.getProject().getArtifactId() + event.getProject().getVersion() );
reccordProjectStarted( event );
}
/**
* @see org.apache.maven.execution.ExecutionListener#forkedProjectSucceeded(org.apache.maven.execution.ExecutionEvent)
*/
public void forkedProjectSucceeded( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println( "forkedProjectSucceeded "
+ event.getProject().getGroupId() + ":"
+ event.getProject().getArtifactId()
+ event.getProject().getVersion());
reccordProjectSucceeded( event );
}
/**
* @see org.apache.maven.execution.ExecutionListener#forkedProjectFailed(org.apache.maven.execution.ExecutionEvent)
*/
public void forkedProjectFailed( ExecutionEvent event ) {
maven3Builder.listener.getLogger().println("forkedProjectFailed " + event.getProject().getGroupId()
+ ":" + event.getProject().getArtifactId()
+ ":" + event.getProject().getVersion());
reccordProjectFailed( event );
}
}
public static boolean markAsSuccess;
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,396 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Olivier Lamy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.maven;
import static hudson.Util.fixNull;
import hudson.AbortException;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Proc;
import hudson.model.BuildListener;
import hudson.model.Computer;
import hudson.model.Executor;
import hudson.model.Hudson;
import hudson.model.JDK;
import hudson.model.Node;
import hudson.model.Run.RunnerAbortedException;
import hudson.model.TaskListener;
import hudson.remoting.Callable;
import hudson.remoting.Channel;
import hudson.remoting.RemoteInputStream;
import hudson.remoting.RemoteOutputStream;
import hudson.remoting.SocketInputStream;
import hudson.remoting.SocketOutputStream;
import hudson.remoting.Which;
import hudson.slaves.Channels;
import hudson.tasks.Maven.MavenInstallation;
import hudson.util.ArgumentListBuilder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Arrays;
import java.util.logging.Logger;
import org.jvnet.hudson.maven3.agent.Maven3Main;
import org.jvnet.hudson.maven3.launcher.Maven3Launcher;
import org.kohsuke.stapler.framework.io.IOException2;
/**
* @author Olivier Lamy
*
*/
public class Maven3ProcessFactory implements ProcessCache.Factory
{
private final MavenModuleSet mms;
private final Launcher launcher;
/**
* Environment variables to be set to the maven process.
* The same variables are exposed to the system property as well.
*/
private final EnvVars envVars;
/**
* Optional working directory. Because of the process reuse, we can't always guarantee
* that the returned Maven process has this as the working directory. But for the
* aggregator style build, the process reuse is disabled, so in practice this always works.
*
* Also, Maven is supposed to work correctly regardless of the process current directory,
* so a good behaving maven project shouldn't rely on the current project.
*/
private final FilePath workDir;
Maven3ProcessFactory(MavenModuleSet mms, Launcher launcher, EnvVars envVars, FilePath workDir) {
this.mms = mms;
this.launcher = launcher;
this.envVars = envVars;
this.workDir = workDir;
}
/**
* Represents a bi-directional connection.
*
* <p>
* This implementation is remoting aware, so it can be safely sent to the remote callable object.
*
* <p>
* When we run Maven on a slave, the master may not have a direct TCP/IP connectivty to the slave.
* That means the {@link Channel} between the master and the Maven needs to be tunneled through
* the channel between master and the slave, then go to TCP socket to the Maven.
*/
private static final class Connection implements Serializable {
public InputStream in;
public OutputStream out;
Connection(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
private Object writeReplace() {
return new Connection(new RemoteInputStream(in),new RemoteOutputStream(out));
}
private Object readResolve() {
// ObjectInputStream seems to access data at byte-level and do not do any buffering,
// so if we are remoted, buffering would be crucial.
this.in = new BufferedInputStream(in);
this.out = new BufferedOutputStream(out);
return this;
}
private static final long serialVersionUID = 1L;
}
interface Acceptor {
Connection accept() throws IOException;
int getPort();
}
/**
* Opens a server socket and returns {@link Acceptor} so that
* we can accept a connection later on it.
*/
private static final class SocketHandler implements Callable<Acceptor,IOException> {
public Acceptor call() throws IOException {
return new AcceptorImpl();
}
private static final long serialVersionUID = 1L;
static final class AcceptorImpl implements Acceptor, Serializable {
private transient final ServerSocket serverSocket;
private transient Socket socket;
AcceptorImpl() throws IOException {
// open a TCP socket to talk to the launched Maven process.
// let the OS pick up a random open port
this.serverSocket = new ServerSocket();
serverSocket.bind(null); // new InetSocketAddress(InetAddress.getLocalHost(),0));
// prevent a hang at the accept method in case the forked process didn't start successfully
serverSocket.setSoTimeout(MavenProcessFactory.socketTimeOut);
}
public Connection accept() throws IOException {
socket = serverSocket.accept();
// we'd only accept one connection
serverSocket.close();
return new Connection(new SocketInputStream(socket),new SocketOutputStream(socket));
}
public int getPort() {
return serverSocket.getLocalPort();
}
/**
* When sent to the remote node, send a proxy.
*/
private Object writeReplace() {
return Channel.current().export(Acceptor.class, this);
}
}
}
/**
* Starts maven process.
*/
public ProcessCache.NewProcess newProcess(BuildListener listener, OutputStream out) throws IOException, InterruptedException {
if(MavenProcessFactory.debug)
listener.getLogger().println("Using env variables: "+ envVars);
try {
final Acceptor acceptor = launcher.getChannel().call(new SocketHandler());
final ArgumentListBuilder cmdLine = buildMavenAgentCmdLine(listener,acceptor.getPort());
String[] cmds = cmdLine.toCommandArray();
final Proc proc = launcher.launch().cmds(cmds).envs(envVars).stdout(out).pwd(workDir).start();
Connection con;
try {
con = acceptor.accept();
} catch (SocketTimeoutException e) {
// failed to connect. Is the process dead?
// if so, the error should have been provided by the launcher already.
// so abort gracefully without a stack trace.
if(!proc.isAlive())
throw new AbortException("Failed to launch Maven. Exit code = "+proc.join());
throw e;
}
return new ProcessCache.NewProcess(
Channels.forProcess("Channel to Maven "+ Arrays.toString(cmds),
Computer.threadPoolForRemoting, new BufferedInputStream(con.in), new BufferedOutputStream(con.out),
listener.getLogger(), proc),
proc);
} catch (IOException e) {
if(fixNull(e.getMessage()).contains("java: not found")) {
// diagnose issue #659
JDK jdk = mms.getJDK();
if(jdk==null)
throw new IOException2(mms.getDisplayName()+" is not configured with a JDK, but your PATH doesn't include Java",e);
}
throw e;
}
}
/**
* Builds the command line argument list to launch the maven process.
*
*/
private ArgumentListBuilder buildMavenAgentCmdLine(BuildListener listener,int tcpPort) 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");
throw new RunnerAbortedException();
}
if(mvn.getHome()==null) {
listener.error("Maven '%s' doesn't have its home set",mvn.getName());
throw new RunnerAbortedException();
}
// find classworlds.jar
String classWorldsJar = launcher.getChannel().call(new GetClassWorldsJar(mvn.getHome(),listener));
boolean isMaster = getCurrentNode()== Hudson.getInstance();
FilePath slaveRoot=null;
if(!isMaster)
slaveRoot = getCurrentNode().getRootPath();
ArgumentListBuilder args = new ArgumentListBuilder();
JDK jdk = getJava(listener);
if(jdk==null) {
args.add("java");
} else {
args.add(jdk.getHome()+"/bin/java"); // use JDK.getExecutable() here ?
}
if(MavenProcessFactory.debugPort!=0)
args.add("-Xrunjdwp:transport=dt_socket,server=y,address="+MavenProcessFactory.debugPort);
if(MavenProcessFactory.yjp)
args.add("-agentlib:yjpagent=tracing");
args.addTokenized(getMavenOpts());
args.add("-cp");
args.add(
(isMaster? Which.jarFile(Maven3Main.class).getAbsolutePath():slaveRoot.child("maven3-agent.jar").getRemote())+
(launcher.isUnix()?":":";")+classWorldsJar);
args.add(Maven3Main.class.getName());
// M2_HOME
args.add(mvn.getHome());
// remoting.jar
String remotingJar = launcher.getChannel().call(new GetRemotingJar());
if(remotingJar==null) {// this shouldn't be possible, but there are still reports indicating this, so adding a probe here.
listener.error("Failed to determine the location of slave.jar");
throw new RunnerAbortedException();
}
args.add(remotingJar);
args.add(isMaster?
Which.jarFile(Maven3Launcher.class).getAbsolutePath():
slaveRoot.child("maven3-interceptor.jar").getRemote());
// TCP/IP port to establish the remoting infrastructure
args.add(tcpPort);
return args;
}
public String getMavenOpts() {
String mavenOpts = mms.getMavenOpts();
if ((mavenOpts==null) || (mavenOpts.trim().length()==0)) {
Node n = getCurrentNode();
if (n!=null) {
try {
String localMavenOpts = n.toComputer().getEnvironment().get("MAVEN_OPTS");
if ((localMavenOpts!=null) && (localMavenOpts.trim().length()>0)) {
mavenOpts = localMavenOpts;
}
} catch (IOException e) {
} catch (InterruptedException e) {
// Don't do anything - this just means the slave isn't running, so we
// don't want to use its MAVEN_OPTS anyway.
}
}
}
return envVars.expand(mavenOpts);
}
public MavenInstallation getMavenInstallation(TaskListener log) throws IOException, InterruptedException {
MavenInstallation mi = mms.getMaven();
if (mi != null) mi = mi.forNode(getCurrentNode(), log).forEnvironment(envVars);
return mi;
}
public JDK getJava(TaskListener log) throws IOException, InterruptedException {
JDK jdk = mms.getJDK();
if (jdk != null) jdk = jdk.forNode(getCurrentNode(), log).forEnvironment(envVars);
return jdk;
}
/**
* Finds classworlds.jar
*/
private static final class GetClassWorldsJar implements Callable<String,IOException> {
private final String mvnHome;
private final TaskListener listener;
private GetClassWorldsJar(String mvnHome, TaskListener listener) {
this.mvnHome = mvnHome;
this.listener = listener;
}
public String call() throws IOException {
File home = new File(mvnHome);
if (MavenProcessFactory.debug)
listener.getLogger().println("Using mvnHome: "+ mvnHome);
File bootDir = new File(home, "boot");
File[] classworlds = bootDir.listFiles(CLASSWORLDS_FILTER);
if(classworlds==null || classworlds.length==0) {
// Maven 2.0.6 puts it to a different place
bootDir = new File(home, "boot");
classworlds = bootDir.listFiles(CLASSWORLDS_FILTER);
if(classworlds==null || classworlds.length==0) {
// FIXME use messages
//listener.error(Messages.MavenProcessFactory_ClassWorldsNotFound(home));
listener.error("classworld not found");
throw new RunnerAbortedException();
}
}
return classworlds[0].getAbsolutePath();
}
}
private static final class GetRemotingJar implements Callable<String,IOException> {
public String call() throws IOException {
return Which.jarFile(hudson.remoting.Launcher.class).getPath();
}
}
/**
* Returns the current {@link Node} on which we are buildling.
*/
private Node getCurrentNode() {
return Executor.currentExecutor().getOwner().getNode();
}
/**
* Locates classworlds jar file.
*
* Note that Maven 3.0 changed the name to plexus-classworlds
*
* <pre>
* $ find tools/ -name "plexus-classworlds*.jar"
* tools/maven-3.0-alpha-2/boot/plexus-classworlds-1.3.jar
* tools/maven-3.0-alpha-3/boot/plexus-classworlds-2.2.2.jar
* tools/maven-3.0-alpha-4/boot/plexus-classworlds-2.2.2.jar
* tools/maven-3.0-alpha-5/boot/plexus-classworlds-2.2.2.jar
* tools/maven-3.0-alpha-6/boot/plexus-classworlds-2.2.2.jar
* </pre>
*/
private static final FilenameFilter CLASSWORLDS_FILTER = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.contains("plexus-classworlds") && name.endsWith(".jar");
}
};
private static final Logger LOGGER = Logger.getLogger(MavenProcessFactory.class.getName());
}

View File

@ -30,6 +30,7 @@ import hudson.slaves.WorkspaceList;
import hudson.slaves.WorkspaceList.Lease;
import hudson.maven.agent.AbortException;
import hudson.model.BuildListener;
import hudson.model.Computer;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.Environment;
@ -40,8 +41,10 @@ import hudson.remoting.Channel;
import hudson.scm.ChangeLogSet;
import hudson.scm.ChangeLogSet.Entry;
import hudson.tasks.BuildWrapper;
import hudson.tasks.Maven.MavenInstallation;
import hudson.util.ArgumentListBuilder;
import org.apache.maven.BuildFailureException;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.lifecycle.LifecycleExecutionException;
@ -407,7 +410,7 @@ public class MavenBuild extends AbstractMavenBuild<MavenModule,MavenBuild> {
}
}
class ProxyImpl2 extends ProxyImpl implements MavenBuildProxy2 {
public class ProxyImpl2 extends ProxyImpl implements MavenBuildProxy2 {
private final SplittableBuildListener listener;
long startTime;
private final OutputStream log;
@ -522,8 +525,35 @@ public class MavenBuild extends AbstractMavenBuild<MavenModule,MavenBuild> {
EnvVars envVars = getEnvironment(listener); // buildEnvironments should be set up first
ProcessCache.MavenProcess process = mavenProcessCache.get(launcher.getChannel(), listener,
new MavenProcessFactory(getParent().getParent(),launcher,envVars,null));
MavenInstallation mvn = getProject().getParent().getMaven();
mvn = mvn.forEnvironment(envVars).forNode(Computer.currentComputer().getNode(), listener);
MavenInformation mavenInformation = getModuleRoot().act( new MavenVersionCallable( mvn.getHome() ));
String mavenVersion = mavenInformation.getVersion();
listener.getLogger().println("Found mavenVersion " + mavenVersion + " from file " + mavenInformation.getVersionResourcePath());
ProcessCache.MavenProcess process = null;
boolean maven3orLater = new ComparableVersion (mavenVersion).compareTo( new ComparableVersion ("3.0") ) >= 0;
if ( maven3orLater )
{
process =
MavenBuild.mavenProcessCache.get( launcher.getChannel(), listener,
new Maven3ProcessFactory( getParent().getParent(), launcher,
envVars, null ) );
}
else
{
process =
MavenBuild.mavenProcessCache.get( launcher.getChannel(), listener,
new MavenProcessFactory( getParent().getParent(), launcher,
envVars, null ) );
}
ArgumentListBuilder margs = new ArgumentListBuilder("-N","-B");
if(mms.usesPrivateRepository())
@ -538,25 +568,33 @@ public class MavenBuild extends AbstractMavenBuild<MavenModule,MavenBuild> {
systemProps.put("hudson.build.number",String.valueOf(getNumber()));
boolean normalExit = false;
try {
Result r = process.call(new Builder(
listener,new ProxyImpl(),
reporters.toArray(new MavenReporter[reporters.size()]), margs.toList(), systemProps));
normalExit = true;
return r;
} finally {
if(normalExit) process.recycle();
else process.discard();
// tear down in reverse order
boolean failed=false;
for( int i=buildEnvironments.size()-1; i>=0; i-- ) {
if (!buildEnvironments.get(i).tearDown(MavenBuild.this,listener)) {
failed=true;
}
if (maven3orLater)
{
// FIXME here for maven 3 builds
return Result.ABORTED;
}
else
{
try {
Result r = process.call(new Builder(
listener,new ProxyImpl(),
reporters.toArray(new MavenReporter[reporters.size()]), margs.toList(), systemProps));
normalExit = true;
return r;
} finally {
if(normalExit) process.recycle();
else process.discard();
// tear down in reverse order
boolean failed=false;
for( int i=buildEnvironments.size()-1; i>=0; i-- ) {
if (!buildEnvironments.get(i).tearDown(MavenBuild.this,listener)) {
failed=true;
}
}
// WARNING The return in the finally clause will trump any return before
if (failed) return Result.FAILURE;
}
// WARNING The return in the finally clause will trump any return before
if (failed) return Result.FAILURE;
}
}

View File

@ -1,7 +1,8 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi,
* Olivier Lamy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,11 +26,9 @@ package hudson.maven;
import hudson.maven.agent.AbortException;
import hudson.maven.agent.Main;
import hudson.maven.agent.PluginManagerInterceptor;
import hudson.maven.agent.PluginManagerListener;
import hudson.maven.reporters.SurefireArchiver;
import hudson.model.BuildListener;
import hudson.model.Hudson;
import hudson.model.Result;
import hudson.remoting.Callable;
import hudson.remoting.Channel;
@ -40,6 +39,7 @@ import hudson.util.IOException2;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
@ -50,7 +50,6 @@ import org.apache.maven.BuildFailureException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.lifecycle.LifecycleExecutorInterceptor;
import org.apache.maven.lifecycle.LifecycleExecutorListener;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.plugin.Mojo;
@ -74,20 +73,8 @@ import org.codehaus.plexus.configuration.PlexusConfiguration;
* @author Kohsuke Kawaguchi
* @since 1.133
*/
public abstract class MavenBuilder implements DelegatingCallable<Result,IOException> {
/**
* Goals to be executed in this Maven execution.
*/
private final List<String> goals;
/**
* Hudson-defined system properties. These will be made available to Maven,
* and accessible as if they are specified as -Dkey=value
*/
private final Map<String,String> systemProps;
/**
* Where error messages and so on are sent.
*/
protected final BuildListener listener;
public abstract class MavenBuilder extends AbstractMavenBuilder implements DelegatingCallable<Result,IOException> {
/**
* Flag needs to be set at the constructor, so that this reflects
@ -102,9 +89,7 @@ public abstract class MavenBuilder implements DelegatingCallable<Result,IOExcept
protected transient /*final*/ List<Future<?>> futures;
protected MavenBuilder(BuildListener listener, List<String> goals, Map<String, String> systemProps) {
this.listener = listener;
this.goals = goals;
this.systemProps = systemProps;
super( listener, goals, systemProps );
}
/**
@ -142,16 +127,30 @@ public abstract class MavenBuilder implements DelegatingCallable<Result,IOExcept
*/
abstract void onReportGenerated(MavenProject project, MavenReportInfo report) throws IOException, InterruptedException, AbortException;
private Class<?> pluginManagerInterceptorClazz;
private Class<?> lifecycleInterceptorClazz;
/**
* This code is executed inside the maven jail process.
*/
public Result call() throws IOException {
// hold a ref on correct classloader for finally call as something is changing tccl
// and not restore it !
ClassLoader mavenJailProcessClassLoader = Thread.currentThread().getContextClassLoader();
try {
futures = new ArrayList<Future<?>>();
Adapter a = new Adapter(this);
callSetListenerWithReflectOnInterceptors( a, mavenJailProcessClassLoader );
/*
PluginManagerInterceptor.setListener(a);
LifecycleExecutorInterceptor.setListener(a);
*/
markAsSuccess = false;
// working around NPE when someone puts a null value into systemProps.
@ -202,46 +201,83 @@ public abstract class MavenBuilder implements DelegatingCallable<Result,IOExcept
listener.getLogger().println(Messages.MavenBuilder_Failed());
return Result.SUCCESS;
}
return Result.FAILURE;
} catch (NoSuchMethodException e) {
throw new IOException2(e);
} catch (IllegalAccessException e) {
throw new IOException2(e);
} catch (NoSuchRealmException e) {
} catch (RuntimeException e) {
throw new IOException2(e);
} catch (InvocationTargetException e) {
throw new IOException2(e);
} catch (ClassNotFoundException e) {
throw new IOException2(e);
}
catch ( NoSuchRealmException e ) {
throw new IOException2(e);
} finally {
PluginManagerInterceptor.setListener(null);
LifecycleExecutorInterceptor.setListener(null);
//PluginManagerInterceptor.setListener(null);
//LifecycleExecutorInterceptor.setListener(null);
callSetListenerWithReflectOnInterceptorsQuietly( null, mavenJailProcessClassLoader );
}
}
private String formatArgs(List<String> args) {
StringBuilder buf = new StringBuilder("Executing Maven: ");
for (String arg : args) {
final String argPassword = "-Dpassword=" ;
String filteredArg = arg ;
// check if current arg is password arg. Then replace password by *****
if (arg.startsWith(argPassword)) {
filteredArg=argPassword+"*********";
}
buf.append(' ').append(filteredArg);
private void callSetListenerWithReflectOnInterceptors( PluginManagerListener pluginManagerListener, ClassLoader cl )
throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException
{
if (pluginManagerInterceptorClazz == null)
{
pluginManagerInterceptorClazz = cl.loadClass( "hudson.maven.agent.PluginManagerInterceptor" );
}
return buf.toString();
}
Method setListenerMethod =
pluginManagerInterceptorClazz.getMethod( "setListener",
new Class[] { cl.loadClass( "hudson.maven.agent.PluginManagerListener" ) } );
setListenerMethod.invoke( null, new Object[] { pluginManagerListener } );
private String format(NumberFormat n, long nanoTime) {
return n.format(nanoTime/1000000);
}
if (lifecycleInterceptorClazz == null)
{
lifecycleInterceptorClazz = cl.loadClass( "org.apache.maven.lifecycle.LifecycleExecutorInterceptor" );
}
setListenerMethod =
lifecycleInterceptorClazz.getMethod( "setListener",
new Class[] { cl.loadClass( "org.apache.maven.lifecycle.LifecycleExecutorListener" ) } );
// since reporters might be from plugins, use the uberjar to resolve them.
public ClassLoader getClassLoader() {
return Hudson.getInstance().getPluginManager().uberClassLoader;
setListenerMethod.invoke( null, new Object[] { pluginManagerListener } );
}
private void callSetListenerWithReflectOnInterceptorsQuietly( PluginManagerListener pluginManagerListener, ClassLoader cl )
{
try
{
callSetListenerWithReflectOnInterceptors(pluginManagerListener, cl);
}
catch ( SecurityException e )
{
throw new RuntimeException( e.getMessage(), e );
}
catch ( IllegalArgumentException e )
{
throw new RuntimeException( e.getMessage(), e );
}
catch ( ClassNotFoundException e )
{
throw new RuntimeException( e.getMessage(), e );
}
catch ( NoSuchMethodException e )
{
throw new RuntimeException( e.getMessage(), e );
}
catch ( IllegalAccessException e )
{
throw new RuntimeException( e.getMessage(), e );
}
catch ( InvocationTargetException e )
{
throw new RuntimeException( e.getMessage(), e );
}
}
/**
* Receives {@link PluginManagerListener} and {@link LifecycleExecutorListener} events

View File

@ -25,10 +25,11 @@ package hudson.maven;
import hudson.Extension;
import hudson.FilePath;
import hudson.maven.agent.AbortException;
import hudson.maven.agent.Main;
import hudson.maven.agent.PluginManagerInterceptor;
import hudson.maven.agent.Maven21Interceptor;
import hudson.model.Computer;
import hudson.model.Hudson;
import hudson.model.TaskListener;
import hudson.remoting.Channel;
import hudson.remoting.Which;
@ -38,8 +39,11 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Zip;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.jvnet.hudson.maven3.agent.Maven3Main;
import org.jvnet.hudson.maven3.launcher.Maven3Launcher;
/**
* When a slave is connected, copy <tt>maven-agent.jar</tt> and <tt>maven-intercepter.jar</tt>
@ -52,8 +56,15 @@ public class MavenComputerListener extends ComputerListener {
public void preOnline(Computer c, Channel channel,FilePath root, TaskListener listener) throws IOException, InterruptedException {
PrintStream logger = listener.getLogger();
copyJar(logger, root, Main.class, "maven-agent");
copyJar(logger, root, PluginManagerInterceptor.class, "maven-interceptor");
copyJar(logger, root, Maven3Main.class, "maven3-agent");
copyJar(logger, root, Maven3Launcher.class, "maven3-interceptor");
copyJar(logger, root, AbortException.class, "maven-interceptor");
copyJar(logger, root, Maven21Interceptor.class, "maven2.1-interceptor");
copyJar(logger, root, ClassWorld.class, "plexus-classworld");
// copy classworlds 1.1 for maven2 builds
root.child( "classworlds.jar" ).copyFrom(getClass().getClassLoader().getResource("classworlds.jar"));
logger.println("Copied classworlds.jar");
}
/**

View File

@ -0,0 +1,153 @@
/**
*
*/
package hudson.maven;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import hudson.model.TaskListener;
import java.io.File;
import java.util.Properties;
import org.sonatype.aether.transfer.TransferListener;
/**
* @author Olivier Lamy
*/
public class MavenEmbedderRequest
{
private TaskListener listener;
private File mavenHome;
private String profiles;
private Properties systemProperties;
private String privateRepository;
private File alternateSettings;
private TransferListener transferListener;
/**
* @param listener
* This is where the log messages from Maven will be recorded.
* @param mavenHome
* Directory of the Maven installation. We read {@code conf/settings.xml}
* from here. Can be null.
* @param profiles
* Profiles to activate/deactivate. Can be null.
* @param systemProperties
* The system properties that the embedded Maven sees. See {@link MavenEmbedder#setSystemProperties(Properties)}.
* @param privateRepository
* Optional private repository to use as the local repository.
* @param alternateSettings
* Optional alternate settings.xml file.
*/
public MavenEmbedderRequest( TaskListener listener, File mavenHome, String profiles, Properties systemProperties,
String privateRepository, File alternateSettings )
{
this.listener = listener;
this.mavenHome = mavenHome;
this.profiles = profiles;
this.systemProperties = systemProperties;
this.privateRepository = privateRepository;
this.alternateSettings = alternateSettings;
}
public TaskListener getListener()
{
return listener;
}
public MavenEmbedderRequest setListener( TaskListener listener )
{
this.listener = listener;
return this;
}
public File getMavenHome()
{
return mavenHome;
}
public MavenEmbedderRequest setMavenHome( File mavenHome )
{
this.mavenHome = mavenHome;
return this;
}
public String getProfiles()
{
return profiles;
}
public MavenEmbedderRequest setProfiles( String profiles )
{
this.profiles = profiles;
return this;
}
public Properties getSystemProperties()
{
return systemProperties;
}
public MavenEmbedderRequest setSystemProperties( Properties systemProperties )
{
this.systemProperties = systemProperties;
return this;
}
public String getPrivateRepository()
{
return privateRepository;
}
public MavenEmbedderRequest setPrivateRepository( String privateRepository )
{
this.privateRepository = privateRepository;
return this;
}
public File getAlternateSettings()
{
return alternateSettings;
}
public MavenEmbedderRequest setAlternateSettings( File alternateSettings )
{
this.alternateSettings = alternateSettings;
return this;
}
public TransferListener getTransferListener()
{
return transferListener;
}
public MavenEmbedderRequest setTransferListener( TransferListener transferListener )
{
this.transferListener = transferListener;
return this;
}
}

View File

@ -23,34 +23,70 @@
*/
package hudson.maven;
import hudson.*;
import hudson.model.*;
import static hudson.Util.fixEmpty;
import static hudson.model.ItemGroupMixIn.loadChildren;
import hudson.CopyOnWrite;
import hudson.Extension;
import hudson.FilePath;
import hudson.Indenter;
import hudson.Util;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.BuildableItemWithBuildWrappers;
import hudson.model.DependencyGraph;
import hudson.model.Descriptor;
import hudson.model.Descriptor.FormException;
import hudson.model.Executor;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.Job;
import hudson.model.Queue;
import hudson.model.Queue.Task;
import hudson.model.ResourceActivity;
import hudson.model.SCMedItem;
import hudson.model.Saveable;
import hudson.model.TopLevelItem;
import hudson.search.CollectionSearchIndex;
import hudson.search.SearchIndexBuilder;
import hudson.tasks.*;
import hudson.tasks.BuildStep;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildWrappers;
import hudson.tasks.Fingerprinter;
import hudson.tasks.JavadocArchiver;
import hudson.tasks.Mailer;
import hudson.tasks.Maven;
import hudson.tasks.Maven.MavenInstallation;
import hudson.tasks.Publisher;
import hudson.tasks.junit.JUnitResultArchiver;
import hudson.util.CopyOnWriteMap;
import hudson.util.DescribableList;
import hudson.util.FormValidation;
import hudson.util.Function1;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import javax.servlet.ServletException;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.util.*;
import static hudson.Util.fixEmpty;
import static hudson.model.ItemGroupMixIn.loadChildren;
/**
* Group of {@link MavenModule}s.
*
@ -144,6 +180,8 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
* If true, do not archive artifacts to the master.
*/
private boolean archivingDisabled = false;
private String mavenVersionUsed;
/**
* Reporters configured at {@link MavenModuleSet} level. Applies to all {@link MavenModule} builds.
@ -598,6 +636,15 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
this.alternateSettings = alternateSettings;
save();
}
public String getMavenVersionUsed() {
return mavenVersionUsed;
}
public void setMavenVersionUsed( String mavenVersionUsed ) throws IOException {
this.mavenVersionUsed = mavenVersionUsed;
save();
}
/**
* If the list of configured goals contain the "-P" option,
@ -837,4 +884,6 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
JUnitResultArchiver.class // done by SurefireArchiver
));
}
}

View File

@ -2,7 +2,7 @@
* The MIT License
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
* Red Hat, Inc., Victor Glushenkov, Alan Harder
* Red Hat, Inc., Victor Glushenkov, Alan Harder, Olivier Lamy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -24,13 +24,29 @@
*/
package hudson.maven;
import hudson.*;
import static hudson.model.Result.FAILURE;
import hudson.AbortException;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.FilePath.FileCallable;
import hudson.Launcher;
import hudson.Util;
import hudson.maven.MavenBuild.ProxyImpl2;
import hudson.maven.reporters.MavenFingerprinter;
import hudson.maven.reporters.MavenMailer;
import hudson.model.*;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.Build;
import hudson.model.BuildListener;
import hudson.model.Cause.UpstreamCause;
import hudson.model.Computer;
import hudson.model.Environment;
import hudson.model.Fingerprint;
import hudson.model.Hudson;
import hudson.model.ParametersAction;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.remoting.Channel;
import hudson.remoting.VirtualChannel;
import hudson.scm.ChangeLogSet;
@ -39,9 +55,33 @@ import hudson.tasks.MailSender;
import hudson.tasks.Maven.MavenInstallation;
import hudson.util.ArgumentListBuilder;
import hudson.util.IOUtils;
import hudson.util.MaskingClassLoader;
import hudson.util.StreamTaskListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.BuildFailureException;
import org.apache.maven.embedder.MavenEmbedderException;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.lifecycle.LifecycleExecutionException;
@ -50,15 +90,9 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.apache.commons.io.FilenameUtils;
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import static hudson.model.Result.FAILURE;
import org.sonatype.aether.transfer.TransferCancelledException;
import org.sonatype.aether.transfer.TransferEvent;
import org.sonatype.aether.transfer.TransferListener;
/**
* {@link Build} for {@link MavenModuleSet}.
@ -427,6 +461,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
PrintStream logger = listener.getLogger();
Result r = null;
try {
EnvVars envVars = getEnvironment(listener);
MavenInstallation mvn = project.getMaven();
if(mvn==null)
@ -435,6 +470,14 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
mvn = mvn.forEnvironment(envVars).forNode(Computer.currentComputer().getNode(), listener);
MavenInformation mavenInformation = getModuleRoot().act( new MavenVersionCallable( mvn.getHome() ));
String mavenVersion = mavenInformation.getVersion();
project.setMavenVersionUsed( mavenVersion );
listener.getLogger().println("Found mavenVersion " + mavenVersion + " from file " + mavenInformation.getVersionResourcePath());
if(!project.isAggregatorStyleBuild()) {
parsePoms(listener, logger, envVars, mvn);
// start module builds
@ -473,9 +516,9 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
// we act as if incrementalBuild is not set if there are no changes.
if (!MavenModuleSetBuild.this.getChangeSet().isEmptySet()
&& project.isIncrementalBuild()) {
// If there are changes for this module, add it.
// Also add it if we've never seen this module before,
// or if the previous build of this module failed or was unstable.
//If there are changes for this module, add it.
// Also add it if we've never seen this module before,
// or if the previous build of this module failed or was unstable.
if ((mb.getPreviousBuiltBuild() == null) ||
(!getChangeSetFor(m).isEmpty())
|| (mb.getPreviousBuiltBuild().getResult().isWorseThan(Result.SUCCESS))) {
@ -499,16 +542,34 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
if(!pom.exists() && parentLoc.exists())
pom = parentLoc;
ProcessCache.MavenProcess process = MavenBuild.mavenProcessCache.get(launcher.getChannel(), slistener,
new MavenProcessFactory(project,launcher,envVars,pom.getParent()));
ProcessCache.MavenProcess process = null;
boolean maven3orLater = MavenUtil.maven3orLater( mavenVersion );
if ( maven3orLater )
{
LOGGER.info( "using maven 3 " + mavenVersion );
process =
MavenBuild.mavenProcessCache.get( launcher.getChannel(), slistener,
new Maven3ProcessFactory( project, launcher, envVars,
pom.getParent() ) );
}
else
{
process =
MavenBuild.mavenProcessCache.get( launcher.getChannel(), slistener,
new MavenProcessFactory( project, launcher, envVars,
pom.getParent() ) );
}
ArgumentListBuilder margs = new ArgumentListBuilder().add("-B").add("-f", pom.getRemote());
if(project.usesPrivateRepository())
margs.add("-Dmaven.repo.local="+getWorkspace().child(".repository"));
// If incrementalBuild is set, and we're on Maven 2.1 or later, *and* there's at least one module
// listed in changedModules, do the Maven incremental build commands - if there are no changed modules,
// We're building everything anyway.
if (project.isIncrementalBuild() && mvn.isMaven2_1(launcher) && !changedModules.isEmpty()) {
boolean maven2_1orLater = new ComparableVersion (mavenVersion).compareTo( new ComparableVersion ("2.1") ) >= 0;
if (project.isIncrementalBuild() && maven2_1orLater && !changedModules.isEmpty()) {
margs.add("-amd");
margs.add("-pl", Util.join(changedModules, ","));
}
@ -527,18 +588,41 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
}
margs.addTokenized(envVars.expand(project.getGoals()));
Builder builder = new Builder(slistener, proxies, project.sortedActiveModules, margs.toList(), envVars);
MavenProbeAction mpa=null;
try {
mpa = new MavenProbeAction(project,process.channel);
addAction(mpa);
r = process.call(builder);
return r;
} finally {
builder.end(launcher);
getActions().remove(mpa);
process.discard();
if (maven3orLater)
{
Map<ModuleName,List<MavenReporter>> reporters = new HashMap<ModuleName, List<MavenReporter>>(project.sortedActiveModules.size());
for (MavenModule mavenModule : project.sortedActiveModules)
{
reporters.put( mavenModule.getModuleName(), mavenModule.createReporters() );
}
Maven3Builder maven3Builder = new Maven3Builder( slistener, proxies, reporters, margs.toList(), envVars );
MavenProbeAction mpa=null;
try {
mpa = new MavenProbeAction(project,process.channel);
addAction(mpa);
r = process.call(maven3Builder);
return r;
} finally {
maven3Builder.end(launcher);
getActions().remove(mpa);
process.discard();
}
} else {
Builder builder = new Builder(slistener, proxies, project.sortedActiveModules, margs.toList(), envVars);
MavenProbeAction mpa=null;
try {
mpa = new MavenProbeAction(project,process.channel);
addAction(mpa);
r = process.call(builder);
return r;
} finally {
builder.end(launcher);
getActions().remove(mpa);
process.discard();
}
}
} finally {
if (r != null) {
@ -741,6 +825,9 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
@Override
public Result call() throws IOException {
try {
if (debug) {
listener.getLogger().println("Builder extends MavenBuilder in call " + Thread.currentThread().getContextClassLoader());
}
return super.call();
} finally {
if(lastProxy!=null)
@ -748,6 +835,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
}
}
@Override
void preBuild(MavenSession session, ReactorManager rm, EventDispatcher dispatcher) throws BuildFailureException, LifecycleExecutionException, IOException, InterruptedException {
// set all modules which are not actually being build (in incremental builds) to NOT_BUILD
@ -832,8 +920,16 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
if(!r.reportGenerated(proxy,project,report,listener))
throw new hudson.maven.agent.AbortException(r+" failed");
}
private static final long serialVersionUID = 1L;
@Override
public ClassLoader getClassLoader()
{
return new MaskingClassLoader( super.getClassLoader() );
}
}
/**
@ -872,7 +968,6 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
private final boolean nonRecursive;
// We're called against the module root, not the workspace, which can cause a lot of confusion.
private final String workspaceProper;
public PomParser(BuildListener listener, MavenInstallation mavenHome, MavenModuleSet project) {
// project cannot be shipped to the remote JVM, so all the relevant properties need to be captured now.
this.listener = listener;
@ -888,7 +983,6 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
this.privateRepository = null;
}
this.alternateSettings = project.getAlternateSettings();
}
/**
@ -956,32 +1050,51 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
if (!settingsLoc.exists() && mrSettingsLoc.exists())
settingsLoc = mrSettingsLoc;
}
if (debug)
{
logger.println("use settingsLoc " + settingsLoc + " , privateRepository " + privateRepository);
}
if ((settingsLoc != null) && (!settingsLoc.exists())) {
throw new AbortException(Messages.MavenModuleSetBuild_NoSuchAlternateSettings(settingsLoc.getAbsolutePath()));
}
try {
MavenEmbedder embedder = MavenUtil.
createEmbedder(listener, mavenHome.getHomeDir(), profiles,
properties, privateRepository, settingsLoc);
MavenProject mp = embedder.readProject(pom);
Map<MavenProject,String> relPath = new HashMap<MavenProject,String>();
MavenUtil.resolveModules(embedder,mp,getRootPath(rootPOMRelPrefix),relPath,listener,nonRecursive);
MavenEmbedderRequest mavenEmbedderRequest = new MavenEmbedderRequest( listener, mavenHome.getHomeDir(),
profiles, properties,
privateRepository, settingsLoc );
mavenEmbedderRequest.setTransferListener( new SimpleTransferListener(listener) );
MavenEmbedder embedder = MavenUtil.createEmbedder( mavenEmbedderRequest );
List<MavenProject> mps = embedder.readProjects( pom,true);
Map<String,MavenProject> canonicalPaths = new HashMap<String, MavenProject>( mps.size() );
for(MavenProject mp : mps) {
canonicalPaths.put( mp.getBasedir().getCanonicalPath(), mp );
}
//MavenUtil.resolveModules(embedder,mp,getRootPath(rootPOMRelPrefix),relPath,listener,nonRecursive);
if(verbose) {
for (Entry<MavenProject, String> e : relPath.entrySet())
logger.printf("Discovered %s at %s\n",e.getKey().getId(),e.getValue());
for (Entry<String,MavenProject> e : canonicalPaths.entrySet())
logger.printf("Discovered %s at %s\n",e.getValue().getId(),e.getKey());
}
List<PomInfo> infos = new ArrayList<PomInfo>();
toPomInfo(mp,null,relPath,infos);
Set<PomInfo> infos = new LinkedHashSet<PomInfo>();
MavenProject rootProject = null;
for (MavenProject mp : mps) {
if (mp.isExecutionRoot()) {
rootProject = mp;
continue;
}
}
// if rootProject is null but no reason :-) use the first one
if (rootProject == null) {
rootProject = mps.get( 0 );
}
toPomInfo(rootProject,null,canonicalPaths,infos);
for (PomInfo pi : infos)
pi.cutCycle();
embedder.stop();
return infos;
return new ArrayList<PomInfo>(infos);
} catch (MavenEmbedderException e) {
throw new MavenExecutionException(e);
} catch (ProjectBuildingException e) {
@ -989,11 +1102,28 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
}
}
private void toPomInfo(MavenProject mp, PomInfo parent, Map<MavenProject,String> relPath, List<PomInfo> infos) {
PomInfo pi = new PomInfo(mp, parent, relPath.get(mp));
private void toPomInfo(MavenProject mp, PomInfo parent, Map<String,MavenProject> abslPath, Set<PomInfo> infos) throws IOException {
String absolutePath = FilenameUtils.normalize( mp.getBasedir().getAbsolutePath());
String relPath = StringUtils.removeStart( absolutePath, this.workspaceProper );
relPath = StringUtils.remove( relPath, '/' );
// root must be marked with only /
if (StringUtils.isBlank( relPath )) {
relPath = "/";
}
PomInfo pi = new PomInfo(mp, parent, relPath);
infos.add(pi);
for (MavenProject child : (List<MavenProject>)mp.getCollectedProjects())
toPomInfo(child,pi,relPath,infos);
for (String modulePath : mp.getModules())
{
if (StringUtils.isBlank( modulePath )) {
continue;
}
File path = new File(mp.getBasedir(), modulePath);
MavenProject child = abslPath.get( path.getCanonicalPath());
toPomInfo(child,pi,abslPath,infos);
}
}
private static final long serialVersionUID = 1L;
@ -1004,10 +1134,60 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
/**
* Extra verbose debug switch.
*/
public static boolean debug = false;
public static boolean debug = Boolean.getBoolean( "hudson.maven.debug" );
@Override
public MavenModuleSet getParent() {// don't know why, but javac wants this
return super.getParent();
}
/**
* will log in the {@link TaskListener} when transferFailed and transferSucceeded
* @author Olivier Lamy
* @since
*/
public static class SimpleTransferListener implements TransferListener
{
private TaskListener taskListener;
public SimpleTransferListener(TaskListener taskListener)
{
this.taskListener = taskListener;
}
public void transferCorrupted( TransferEvent arg0 )
throws TransferCancelledException
{
// no op
}
public void transferFailed( TransferEvent transferEvent )
{
taskListener.getLogger().println("failed to transfer " + transferEvent.getException().getMessage());
}
public void transferInitiated( TransferEvent arg0 )
throws TransferCancelledException
{
// no op
}
public void transferProgressed( TransferEvent arg0 )
throws TransferCancelledException
{
// no op
}
public void transferStarted( TransferEvent arg0 )
throws TransferCancelledException
{
// no op
}
public void transferSucceeded( TransferEvent transferEvent )
{
taskListener.getLogger().println( "downloaded artifact " + transferEvent.getResource().getRepositoryUrl()
+ "/" + transferEvent.getResource().getResourceName() );
}
}
}

View File

@ -32,7 +32,6 @@ import hudson.slaves.Channels;
import static hudson.Util.fixNull;
import hudson.maven.agent.Main;
import hudson.maven.agent.Maven21Interceptor;
import hudson.maven.agent.PluginManagerInterceptor;
import hudson.maven.ProcessCache.NewProcess;
import hudson.model.BuildListener;
import hudson.model.Computer;
@ -169,7 +168,7 @@ final class MavenProcessFactory implements ProcessCache.Factory {
this.serverSocket = new ServerSocket();
serverSocket.bind(null); // new InetSocketAddress(InetAddress.getLocalHost(),0));
// prevent a hang at the accept method in case the forked process didn't start successfully
serverSocket.setSoTimeout(30*1000);
serverSocket.setSoTimeout(socketTimeOut);
}
public Connection accept() throws IOException {
@ -200,6 +199,7 @@ final class MavenProcessFactory implements ProcessCache.Factory {
if(debug)
listener.getLogger().println("Using env variables: "+ envVars);
try {
//launcher.getChannel().export( type, instance )
final Acceptor acceptor = launcher.getChannel().call(new SocketHandler());
Charset charset;
try {
@ -282,10 +282,14 @@ final class MavenProcessFactory implements ProcessCache.Factory {
args.addTokenized(getMavenOpts());
args.add("-cp");
args.add(
(isMaster? Which.jarFile(Main.class).getAbsolutePath():slaveRoot.child("maven-agent.jar").getRemote())+
(launcher.isUnix()?":":";")+classWorldsJar);
args.add( "-cp" );
String classPath =
( isMaster ? Which.jarFile( Main.class ).getAbsolutePath()
: slaveRoot.child( "maven-agent.jar" ).getRemote() )
+ ( launcher.isUnix() ? ":" : ";" )
+ ( isMaster ? classWorldsJar : slaveRoot.child( "classworlds.jar" ).getRemote() );
args.add( classPath );
//+classWorldsJar);
args.add(Main.class.getName());
// M2_HOME
@ -301,7 +305,7 @@ final class MavenProcessFactory implements ProcessCache.Factory {
// interceptor.jar
args.add(isMaster?
Which.jarFile(PluginManagerInterceptor.class).getAbsolutePath():
Which.jarFile(hudson.maven.agent.AbortException.class).getAbsolutePath():
slaveRoot.child("maven-interceptor.jar").getRemote());
// TCP/IP port to establish the remoting infrastructure
@ -313,7 +317,7 @@ final class MavenProcessFactory implements ProcessCache.Factory {
Which.jarFile(Maven21Interceptor.class).getAbsolutePath():
slaveRoot.child("maven2.1-interceptor.jar").getRemote());
}
return args;
}
@ -440,6 +444,9 @@ final class MavenProcessFactory implements ProcessCache.Factory {
if(port!=null)
debugPort = Integer.parseInt(port);
}
public static int socketTimeOut = Integer.parseInt( System.getProperty( "hudson.maven.socketTimeOut", Integer.toString( 30*1000 ) ) );
private static final Logger LOGGER = Logger.getLogger(MavenProcessFactory.class.getName());
}

View File

@ -25,32 +25,33 @@ package hudson.maven;
import hudson.AbortException;
import hudson.Util;
import hudson.model.BuildListener;
import hudson.model.TaskListener;
import hudson.model.AbstractProject;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Hudson;
import hudson.model.TaskListener;
import hudson.tasks.Maven.MavenInstallation;
import hudson.tasks.Maven.ProjectWithMaven;
import org.apache.maven.embedder.MavenEmbedderException;
import org.apache.maven.embedder.MavenEmbedderLogger;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.commons.io.IOUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
/**
* @author Kohsuke Kawaguchi
*/
@ -107,12 +108,12 @@ public class MavenUtil {
systemProperties = ((MavenModuleSet) project).getMavenProperties();
}
return createEmbedder(listener,
return createEmbedder(new MavenEmbedderRequest(listener,
m!=null?m.getHomeDir():null,
profiles,
systemProperties,
privateRepository,
settingsLoc);
settingsLoc ));
}
public static MavenEmbedder createEmbedder(TaskListener listener, File mavenHome, String profiles) throws MavenEmbedderException, IOException {
@ -123,45 +124,23 @@ public class MavenUtil {
return createEmbedder(listener,mavenHome,profiles,systemProperties,null);
}
public static MavenEmbedder createEmbedder(TaskListener listener, File mavenHome, String profiles, Properties systemProperties,
String privateRepository) throws MavenEmbedderException, IOException {
return createEmbedder(listener,mavenHome,profiles,systemProperties,privateRepository,null);
public static MavenEmbedder createEmbedder( TaskListener listener, File mavenHome, String profiles,
Properties systemProperties, String privateRepository )
throws MavenEmbedderException, IOException
{
return createEmbedder( new MavenEmbedderRequest( listener, mavenHome, profiles, systemProperties,
privateRepository, null ) );
}
/**
* Creates a fresh {@link MavenEmbedder} instance.
*
* @param listener
* This is where the log messages from Maven will be recorded.
* @param mavenHome
* Directory of the Maven installation. We read {@code conf/settings.xml}
* from here. Can be null.
* @param profiles
* Profiles to activate/deactivate. Can be null.
* @param systemProperties
* The system properties that the embedded Maven sees. See {@link MavenEmbedder#setSystemProperties(Properties)}.
* @param privateRepository
* Optional private repository to use as the local repository.
* @param alternateSettings
* Optional alternate settings.xml file.
*/
public static MavenEmbedder createEmbedder(TaskListener listener, File mavenHome, String profiles, Properties systemProperties,
String privateRepository, File alternateSettings) throws MavenEmbedderException, IOException {
MavenEmbedder maven = new MavenEmbedder(mavenHome);
ClassLoader cl = MavenUtil.class.getClassLoader();
maven.setClassLoader(new MaskingClassLoader(cl));
EmbedderLoggerImpl logger = new EmbedderLoggerImpl(listener);
if(debugMavenEmbedder) logger.setThreshold(MavenEmbedderLogger.LEVEL_DEBUG);
maven.setLogger(logger);
{
Enumeration<URL> e = cl.getResources("META-INF/plexus/components.xml");
while (e.hasMoreElements()) {
URL url = e.nextElement();
LOGGER.fine("components.xml from "+url);
}
}
public static MavenEmbedder createEmbedder(MavenEmbedderRequest mavenEmbedderRequest) throws MavenEmbedderException, IOException {
MavenRequest mavenRequest = new MavenRequest();
// make sure ~/.m2 exists to avoid http://www.nabble.com/BUG-Report-tf3401736.html
File m2Home = new File(MavenEmbedder.userHome, ".m2");
m2Home.mkdirs();
@ -169,22 +148,57 @@ public class MavenUtil {
throw new AbortException("Failed to create "+m2Home+
"\nSee https://hudson.dev.java.net/cannot-create-.m2.html");
if (privateRepository!=null)
maven.setLocalRepositoryDirectory(new File(privateRepository));
if (mavenEmbedderRequest.getPrivateRepository()!=null)
mavenRequest.setLocalRepositoryPath( mavenEmbedderRequest.getPrivateRepository() );
maven.setProfiles(profiles);
if (mavenEmbedderRequest.getProfiles() != null) {
mavenRequest.setProfiles(Arrays.asList( StringUtils.split( mavenEmbedderRequest.getProfiles(), "," ) ));
}
if (alternateSettings!=null)
maven.setAlternateSettings(alternateSettings);
if ( mavenEmbedderRequest.getAlternateSettings() != null ) {
mavenRequest.setUserSettingsFile( mavenEmbedderRequest.getAlternateSettings().getAbsolutePath() );
} else {
mavenRequest.setUserSettingsFile( new File( m2Home, "settings.xml" ).getAbsolutePath() );
}
maven.setSystemProperties(systemProperties);
maven.start();
// FIXME configure those !!
mavenRequest.setGlobalSettingsFile( new File( mavenEmbedderRequest.getMavenHome(), "conf/settings.xml" ).getAbsolutePath() );
// TODO olamy check this sould be userProperties
mavenRequest.setSystemProperties(mavenEmbedderRequest.getSystemProperties());
if (mavenEmbedderRequest.getTransferListener() != null) {
if (debugMavenEmbedder) {
mavenEmbedderRequest.getListener().getLogger()
.println( "use transfertListener " + mavenEmbedderRequest.getTransferListener().getClass().getName() );
}
mavenRequest.setTransferListener( mavenEmbedderRequest.getTransferListener() );
}
EmbedderLoggerImpl logger =
new EmbedderLoggerImpl( mavenEmbedderRequest.getListener(), debugMavenEmbedder ? org.codehaus.plexus.logging.Logger.LEVEL_DEBUG
: org.codehaus.plexus.logging.Logger.LEVEL_INFO );
mavenRequest.setMavenLoggerManager( logger );
ClassLoader cl = MavenUtil.class.getClassLoader();
// TODO check this MaskingClassLoader with maven 3 artifacts
MavenEmbedder maven = new MavenEmbedder( new MaskingClassLoader(cl), mavenRequest );
{
Enumeration<URL> e = cl.getResources("META-INF/plexus/components.xml");
while (e.hasMoreElements()) {
URL url = e.nextElement();
LOGGER.fine("components.xml from "+url);
}
}
return maven;
}
/**
* @deprecated MavenEmbedder has now a method to read all projects
* Recursively resolves module POMs that are referenced from
* the given {@link MavenProject} and parses them into
* {@link MavenProject}s.
@ -198,39 +212,43 @@ public class MavenUtil {
*
* @throws AbortException
* errors will be reported to the listener and the exception thrown.
* @throws MavenEmbedderException
*/
public static void resolveModules(MavenEmbedder embedder, MavenProject project,
String rel, Map<MavenProject,String> relativePathInfo,
BuildListener listener, boolean nonRecursive) throws ProjectBuildingException,
AbortException {
File basedir = project.getFile().getParentFile();
relativePathInfo.put(project,rel);
public static void resolveModules( MavenEmbedder embedder, MavenProject project, String rel,
Map<MavenProject, String> relativePathInfo, BuildListener listener,
boolean nonRecursive )
throws ProjectBuildingException, AbortException, MavenEmbedderException
{
if (!nonRecursive) {
List<MavenProject> modules = new ArrayList<MavenProject>();
for (String modulePath : (List<String>) project.getModules()) {
if (Util.fixEmptyAndTrim(modulePath)!=null) {
File moduleFile = new File(basedir, modulePath);
if (moduleFile.exists() && moduleFile.isDirectory()) {
moduleFile = new File(basedir, modulePath + "/pom.xml");
}
if(!moduleFile.exists())
throw new AbortException(moduleFile+" is referenced from "+project.getFile()+" but it doesn't exist");
String relativePath = rel;
if(relativePath.length()>0) relativePath+='/';
relativePath+=modulePath;
MavenProject child = embedder.readProject(moduleFile);
resolveModules(embedder,child,relativePath,relativePathInfo,listener,nonRecursive);
modules.add(child);
}
}
project.setCollectedProjects(modules);
}
File basedir = project.getFile().getParentFile();
relativePathInfo.put( project, rel );
List<MavenProject> modules = new ArrayList<MavenProject>();
if ( !nonRecursive ) {
for ( String modulePath : project.getModules()) {
if ( Util.fixEmptyAndTrim( modulePath ) != null ) {
File moduleFile = new File( basedir, modulePath );
if ( moduleFile.exists() && moduleFile.isDirectory() ) {
moduleFile = new File( basedir, modulePath + "/pom.xml" );
}
if ( !moduleFile.exists() )
throw new AbortException( moduleFile + " is referenced from " + project.getFile()
+ " but it doesn't exist" );
String relativePath = rel;
if ( relativePath.length() > 0 )
relativePath += '/';
relativePath += modulePath;
MavenProject child = embedder.readProject( moduleFile );
resolveModules( embedder, child, relativePath, relativePathInfo, listener, nonRecursive );
modules.add( child );
}
}
}
project.setCollectedProjects( modules );
}
/**
@ -305,11 +323,20 @@ public class MavenUtil {
};
}
}
public static boolean maven3orLater(String mavenVersion) {
// null or empty so false !
if (StringUtils.isBlank( mavenVersion )) {
return false;
}
return new ComparableVersion (mavenVersion).compareTo( new ComparableVersion ("3.0") ) >= 0;
}
/**
* If set to true, maximize the logging level of Maven embedder.
*/
public static boolean debugMavenEmbedder = false;
public static boolean debugMavenEmbedder = Boolean.getBoolean( "debugMavenEmbedder" );
private static final Logger LOGGER = Logger.getLogger(MavenUtil.class.getName());
}

View File

@ -0,0 +1,64 @@
package hudson.maven;
/*
* The MIT License
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc. Olivier Lamy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import hudson.remoting.Callable;
import java.io.File;
import java.io.IOException;
import org.kohsuke.stapler.framework.io.IOException2;
/**
*
* @author Olivier Lamy
* @since 3.0
*
*/
public class MavenVersionCallable
implements Callable<MavenInformation, IOException>
{
private final String mavenHome;
public MavenVersionCallable( String mavenHome )
{
this.mavenHome = mavenHome;
}
public MavenInformation call()
throws IOException
{
try
{
return MavenEmbedderUtils.getMavenVersion( new File(mavenHome) );
}
catch ( MavenEmbedderException e )
{
throw new IOException2( e );
}
}
}

View File

@ -25,6 +25,9 @@ package hudson.maven;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.codehaus.classworlds.ClassRealm;
import org.codehaus.classworlds.ClassRealmAdapter;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup;
@ -39,6 +42,7 @@ import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
import hudson.util.InvocationInterceptor;
import hudson.util.ReflectionUtils;
/**
* Information about Mojo to be executed. This object provides
@ -126,13 +130,26 @@ public class MojoInfo {
public <T> T getConfigurationValue(String configName, Class<T> type) throws ComponentConfigurationException {
PlexusConfiguration child = configuration.getChild(configName);
if(child==null) return null; // no such config
ClassLoader cl = null;
PluginDescriptor pd = mojoExecution.getMojoDescriptor().getPluginDescriptor();
// for maven2 builds ClassRealm doesn't extends ClassLoader !
// so check stuff with reflection
Method method = ReflectionUtils.getPublicMethodNamed( pd.getClass(), "getClassRealm" );
if ( ReflectionUtils.invokeMethod( method, pd ) instanceof ClassRealm)
{
ClassRealm cr = (ClassRealm) ReflectionUtils.invokeMethod( method, pd );
cl = cr.getClassLoader();
} else {
cl = mojoExecution.getMojoDescriptor().getPluginDescriptor().getClassRealm();
}
ConfigurationConverter converter = converterLookup.lookupConverterForType(type);
return type.cast(converter.fromConfiguration(converterLookup,child,type,
// the implementation seems to expect the type of the bean for which the configuration is done
// in this parameter, but we have no such type. So passing in a dummy
Object.class,
mojoExecution.getMojoDescriptor().getPluginDescriptor().getClassRealm().getClassLoader(),
cl,
expressionEvaluator));
}

View File

@ -23,6 +23,7 @@
*/
package hudson.maven;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.model.CiManagement;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Extension;
@ -94,6 +95,16 @@ final class PomInfo implements Serializable {
* Parent module.
*/
public final PomInfo parent;
/**
* maven groupId
*/
private final String groupId;
/**
* maven artifactId
*/
private final String artifactId;
public final Notifier mailNotifier;
@ -140,6 +151,9 @@ final class PomInfo implements Serializable {
this.mailNotifier = mailNotifier;
} else
this.mailNotifier = null;
this.groupId = project.getGroupId();
this.artifactId = project.getArtifactId();
}
/**
@ -189,4 +203,29 @@ final class PomInfo implements Serializable {
}
private static final long serialVersionUID = 1L;
@Override
public int hashCode()
{
int hash = 23 + this.groupId == null ? 1 : this.groupId.hashCode();
hash += this.artifactId == null ? 1 : this.artifactId.hashCode();
return hash;
}
@Override
public boolean equals( Object obj )
{
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof PomInfo)) {
return false;
}
PomInfo pomInfo = (PomInfo) obj;
return StringUtils.equals( pomInfo.groupId, this.groupId )
&& StringUtils.equals( pomInfo.artifactId, this.artifactId );
}
}

View File

@ -23,8 +23,8 @@
*/
package hudson.maven;
import hudson.Launcher;
import hudson.Extension;
import hudson.Launcher;
import hudson.Util;
import hudson.maven.reporters.MavenAbstractArtifactRecord;
import hudson.model.AbstractBuild;
@ -32,22 +32,32 @@ import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Result;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import hudson.tasks.BuildStepMonitor;
import hudson.util.FormValidation;
import net.sf.json.JSONObject;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.embedder.MavenEmbedderException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.Authentication;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.repository.Proxy;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
/**
* {@link Publisher} for {@link MavenModuleSetBuild} to deploy artifacts
@ -96,8 +106,8 @@ public class RedeployPublisher extends Recorder {
return true;
}
MavenAbstractArtifactRecord mar = getAction(build);
if(mar==null) {
List<MavenAbstractArtifactRecord> mars = getActions( build, listener );
if(mars==null || mars.isEmpty()) {
listener.getLogger().println("No artifacts are recorded. Is this a Maven project?");
build.setResult(Result.FAILURE);
return true;
@ -108,16 +118,16 @@ public class RedeployPublisher extends Recorder {
MavenEmbedder embedder = MavenUtil.createEmbedder(listener,build);
ArtifactRepositoryLayout layout =
(ArtifactRepositoryLayout) embedder.getContainer().lookup( ArtifactRepositoryLayout.ROLE,"default");
(ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.ROLE,"default");
ArtifactRepositoryFactory factory =
(ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE);
ArtifactRepository repository = factory.createDeploymentArtifactRepository(
final ArtifactRepository repository = factory.createDeploymentArtifactRepository(
id, url, layout, uniqueVersion);
WrappedArtifactRepository repo = new WrappedArtifactRepository(repository,uniqueVersion);
for (MavenAbstractArtifactRecord mar : mars)
mar.deploy(embedder,repo,listener);
mar.deploy(embedder,repository,listener);
embedder.stop();
return true;
} catch (MavenEmbedderException e) {
e.printStackTrace(listener.error(e.getMessage()));
@ -131,6 +141,8 @@ public class RedeployPublisher extends Recorder {
return true;
}
/**
* Obtains the {@link MavenAbstractArtifactRecord} that we'll work on.
* <p>
@ -139,6 +151,23 @@ public class RedeployPublisher extends Recorder {
protected MavenAbstractArtifactRecord getAction(AbstractBuild<?, ?> build) {
return build.getAction(MavenAbstractArtifactRecord.class);
}
protected List<MavenAbstractArtifactRecord> getActions(AbstractBuild<?, ?> build, BuildListener listener) {
List<MavenAbstractArtifactRecord> actions = new ArrayList<MavenAbstractArtifactRecord>();
if (!(build instanceof MavenModuleSetBuild)) {
return actions;
}
for (Entry<MavenModule, MavenBuild> e : ((MavenModuleSetBuild)build).getModuleLastBuilds().entrySet()) {
MavenAbstractArtifactRecord a = e.getValue().getAction( MavenAbstractArtifactRecord.class );
if (a == null) {
listener.getLogger().println("No artifacts are recorded for module" + e.getKey().getName() + ". Is this a Maven project?");
} else {
actions.add( a );
}
}
return actions;
}
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
@ -190,4 +219,126 @@ public class RedeployPublisher extends Recorder {
return FormValidation.ok();
}
}
//---------------------------------------------
public static class WrappedArtifactRepository implements ArtifactRepository {
private ArtifactRepository artifactRepository;
private boolean uniqueVersion;
public WrappedArtifactRepository (ArtifactRepository artifactRepository, boolean uniqueVersion)
{
this.artifactRepository = artifactRepository;
this.uniqueVersion = uniqueVersion;
}
public String pathOf( Artifact artifact )
{
return artifactRepository.pathOf( artifact );
}
public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
{
return artifactRepository.pathOfRemoteRepositoryMetadata( artifactMetadata );
}
public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
{
return artifactRepository.pathOfLocalRepositoryMetadata( metadata, repository );
}
public String getUrl()
{
return artifactRepository.getUrl();
}
public void setUrl( String url )
{
artifactRepository.setUrl( url );
}
public String getBasedir()
{
return artifactRepository.getBasedir();
}
public String getProtocol()
{
return artifactRepository.getProtocol();
}
public String getId()
{
return artifactRepository.getId();
}
public void setId( String id )
{
artifactRepository.setId( id );
}
public ArtifactRepositoryPolicy getSnapshots()
{
return artifactRepository.getSnapshots();
}
public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy policy )
{
artifactRepository.setSnapshotUpdatePolicy( policy );
}
public ArtifactRepositoryPolicy getReleases()
{
return artifactRepository.getReleases();
}
public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy policy )
{
artifactRepository.setReleaseUpdatePolicy( policy );
}
public ArtifactRepositoryLayout getLayout()
{
return artifactRepository.getLayout();
}
public void setLayout( ArtifactRepositoryLayout layout )
{
artifactRepository.setLayout( layout );
}
public String getKey()
{
return artifactRepository.getKey();
}
public boolean isUniqueVersion()
{
return this.uniqueVersion;
}
public void setUniqueVersion(boolean uniqueVersion) {
this.uniqueVersion = uniqueVersion;
}
public boolean isBlacklisted()
{
return artifactRepository.isBlacklisted();
}
public void setBlacklisted( boolean blackListed )
{
artifactRepository.setBlacklisted( blackListed );
}
public Artifact find( Artifact artifact )
{
return artifactRepository.find( artifact );
}
public List<String> findVersions( Artifact artifact )
{
return artifactRepository.findVersions( artifact );
}
public boolean isProjectAware()
{
return artifactRepository.isProjectAware();
}
public void setAuthentication( Authentication authentication )
{
artifactRepository.setAuthentication( authentication );
}
public Authentication getAuthentication()
{
return artifactRepository.getAuthentication();
}
public void setProxy( Proxy proxy )
{
artifactRepository.setProxy( proxy );
}
public Proxy getProxy()
{
return artifactRepository.getProxy();
}
}
}

View File

@ -25,34 +25,24 @@ package hudson.maven.reporters;
import hudson.console.AnnotatedLargeText;
import hudson.maven.MavenEmbedder;
import hudson.maven.MavenEmbedderException;
import hudson.maven.MavenUtil;
import hudson.maven.RedeployPublisher.WrappedArtifactRepository;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BallColor;
import hudson.model.BuildBadgeAction;
import hudson.model.Result;
import hudson.model.TaskAction;
import hudson.model.TaskListener;
import hudson.model.TaskThread;
import hudson.model.BuildBadgeAction;
import hudson.model.TaskThread.ListenerAndText;
import hudson.security.Permission;
import hudson.security.ACL;
import hudson.security.Permission;
import hudson.util.Iterators;
import hudson.widgets.HistoryWidget;
import hudson.widgets.HistoryWidget.Adapter;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.embedder.MavenEmbedderException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.HttpRedirect;
import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
@ -60,6 +50,19 @@ import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.ServletException;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
/**
* UI to redeploy artifacts after the fact.
*
@ -204,16 +207,15 @@ public abstract class MavenAbstractArtifactRecord<T extends AbstractBuild<?,?>>
try {
MavenEmbedder embedder = MavenUtil.createEmbedder(listener,getBuild());
ArtifactRepositoryLayout layout =
(ArtifactRepositoryLayout) embedder.getContainer().lookup( ArtifactRepositoryLayout.ROLE,"default");
(ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.class,"default");
ArtifactRepositoryFactory factory =
(ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE);
ArtifactRepository repository = factory.createDeploymentArtifactRepository(
id, repositoryUrl, layout, uniqueVersion);
WrappedArtifactRepository repo = new WrappedArtifactRepository(repository, uniqueVersion);
deploy(embedder,repo,listener);
deploy(embedder,repository,listener);
embedder.stop();
record.result = Result.SUCCESS;
} finally {
if(record.result==null)

View File

@ -26,20 +26,21 @@ package hudson.maven.reporters;
import hudson.maven.MavenAggregatedReport;
import hudson.maven.MavenBuild;
import hudson.maven.MavenEmbedder;
import hudson.maven.MavenEmbedderException;
import hudson.maven.MavenModule;
import hudson.maven.MavenModuleSet;
import hudson.maven.MavenModuleSetBuild;
import hudson.model.Action;
import hudson.model.TaskListener;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.embedder.MavenEmbedderException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
/**
* Redeploy action for the entire {@link MavenModuleSetBuild}.
*

View File

@ -36,11 +36,14 @@ import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import com.google.common.collect.Maps;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.logging.Logger;
/**
@ -145,14 +148,14 @@ public final class MavenArtifact implements Serializable {
// in the repository during deployment. So simulate that behavior if that's necessary.
final String canonicalExtension = canonicalName.substring(canonicalName.lastIndexOf('.')+1);
ArtifactHandler ah = handlerManager.getArtifactHandler(type);
// Fix for HUDSON-3814 - changed from comparing against canonical extension to canonicalName.endsWith.
if(!canonicalName.endsWith(ah.getExtension())) {
handlerManager.addHandlers(Collections.singletonMap(type,
new DefaultArtifactHandler(type) {
Map<String,ArtifactHandler> handlers = Maps.newHashMap();
handlers.put( type, new DefaultArtifactHandler(type) {
public String getExtension() {
return canonicalExtension;
}
}));
} } );
// Fix for HUDSON-3814 - changed from comparing against canonical extension to canonicalName.endsWith.
if(!canonicalName.endsWith(ah.getExtension())) {
handlerManager.addHandlers(handlers);
}
Artifact a = factory.createArtifactWithClassifier(groupId, artifactId, version, type, classifier);

View File

@ -27,10 +27,19 @@ import hudson.maven.AggregatableAction;
import hudson.maven.MavenAggregatedReport;
import hudson.maven.MavenBuild;
import hudson.maven.MavenEmbedder;
import hudson.maven.MavenEmbedderException;
import hudson.maven.MavenModule;
import hudson.maven.MavenModuleSetBuild;
import hudson.maven.MavenUtil;
import hudson.maven.RedeployPublisher.WrappedArtifactRepository;
import hudson.model.Action;
import hudson.model.TaskListener;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
import java.util.Map;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.deployer.ArtifactDeployer;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
@ -39,15 +48,9 @@ import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.installer.ArtifactInstallationException;
import org.apache.maven.artifact.installer.ArtifactInstaller;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.embedder.MavenEmbedderException;
import org.apache.maven.project.artifact.ProjectArtifactMetadata;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
import java.util.Map;
/**
* {@link Action} that remembers {@link MavenArtifact artifact}s that are built.
*
@ -105,33 +108,43 @@ public class MavenArtifactRecord extends MavenAbstractArtifactRecord<MavenBuild>
@Override
public void deploy(MavenEmbedder embedder, ArtifactRepository deploymentRepository, TaskListener listener) throws MavenEmbedderException, IOException, ComponentLookupException, ArtifactDeploymentException {
ArtifactHandlerManager handlerManager = (ArtifactHandlerManager) embedder.lookup(ArtifactHandlerManager.ROLE);
ArtifactDeployer deployer = (ArtifactDeployer) embedder.lookup(ArtifactDeployer.ROLE);
ArtifactFactory factory = (ArtifactFactory) embedder.lookup(ArtifactFactory.ROLE);
ArtifactHandlerManager handlerManager = embedder.lookup(ArtifactHandlerManager.class);
ArtifactFactory factory = embedder.lookup(ArtifactFactory.class);
PrintStream logger = listener.getLogger();
boolean maven3orLater = MavenUtil.maven3orLater( parent.getModuleSetBuild().getProject().getMavenVersionUsed());
if (!deploymentRepository.isUniqueVersion() && maven3orLater) {
logger.println("uniqueVersion == false is not anymore supported in maven 3");
((WrappedArtifactRepository) deploymentRepository).setUniqueVersion( true );
}
Artifact main = mainArtifact.toArtifact(handlerManager,factory,parent);
if(!isPOM())
main.addMetadata(new ProjectArtifactMetadata(main,pomArtifact.getFile(parent)));
// deploy the main artifact. This also deploys the POM
logger.println(Messages.MavenArtifact_DeployingMainArtifact(main.getFile().getName()));
deployer.deploy(main.getFile(),main,deploymentRepository,embedder.getLocalRepository());
deployMavenArtifact( main, deploymentRepository, embedder );
for (MavenArtifact aa : attachedArtifacts) {
Artifact a = aa.toArtifact(handlerManager,factory, parent);
logger.println(Messages.MavenArtifact_DeployingAttachedArtifact(a.getFile().getName()));
deployer.deploy(a.getFile(),a,deploymentRepository,embedder.getLocalRepository());
deployMavenArtifact( a, deploymentRepository, embedder );
}
}
protected void deployMavenArtifact(Artifact artifact, ArtifactRepository deploymentRepository, MavenEmbedder embedder)
throws ArtifactDeploymentException, ComponentLookupException {
ArtifactDeployer deployer = embedder.lookup(ArtifactDeployer.class,"maven2");
deployer.deploy(artifact.getFile(),artifact,deploymentRepository,embedder.getLocalRepository());
}
/**
* Installs the artifact to the local Maven repository.
*/
public void install(MavenEmbedder embedder) throws MavenEmbedderException, IOException, ComponentLookupException, ArtifactInstallationException {
ArtifactHandlerManager handlerManager = (ArtifactHandlerManager) embedder.lookup(ArtifactHandlerManager.ROLE);
ArtifactInstaller installer = (ArtifactInstaller) embedder.lookup(ArtifactInstaller.class.getName());
ArtifactFactory factory = (ArtifactFactory) embedder.lookup(ArtifactFactory.class.getName());
ArtifactHandlerManager handlerManager = embedder.lookup(ArtifactHandlerManager.class);
ArtifactInstaller installer = embedder.lookup(ArtifactInstaller.class);
ArtifactFactory factory = embedder.lookup(ArtifactFactory.class);
Artifact main = mainArtifact.toArtifact(handlerManager,factory,parent);
if(!isPOM())

View File

@ -25,6 +25,7 @@ package hudson.maven.reporters;
import hudson.Util;
import hudson.Extension;
import hudson.maven.Maven3Builder;
import hudson.maven.MavenBuild;
import hudson.maven.MavenBuildProxy;
import hudson.maven.MavenBuildProxy.BuildCallable;
@ -126,6 +127,10 @@ public class SurefireArchiver extends MavenReporter {
if(failCount>0 && error instanceof MojoFailureException) {
MavenBuilder.markAsSuccess = true;
}
// TODO currenlty error is empty : will be here with maven 3.0.2+
if(failCount>0) {
Maven3Builder.markAsSuccess = true;
}
}
return true;

View File

@ -26,7 +26,7 @@ Build=Byg
Maven\ Version=Maven version
Use\ private\ Maven\ repository=Benyt et privat Mavenarkiv
Incremental\ build\ -\ only\ build\ changed\ modules=Inkrementel byg - byg kun moduler med \u00e6ndringer
Maven\ Version.error.1=Hudson har brug for at vide hvor din Maven2 er installeret.
Maven\ Version.error.1=Hudson har brug for at vide hvor din Maven2/3 er installeret.
Goals\ and\ options=M\u00e5l og tilvalg
Build\ modules\ in\ parallel=Byg moduler i parallel
Build\ Settings=Byggeindstillinger

View File

@ -31,5 +31,5 @@ Use\ private\ Maven\ repository=Verwende privates Maven-Repository
Alternate\ settings\ file=Alternative Settings-Datei
Build\ whenever\ a\ SNAPSHOT\ dependency\ is\ built=Baue dieses Projekt, wenn eine SNAPSHOT-Abhängigkeit gebaut wurde
Incremental\ build\ -\ only\ build\ changed\ modules=Inkrementelles Bauen - baut nur geänderte Module
Maven\ Version.error.1=Hudson muss Ihr Maven2-Installationsverzeichnis kennen.
Maven\ Version.error.1=Hudson muss Ihr Maven2/3-Installationsverzeichnis kennen.
Maven\ Version.error.2=Bitte geben Sie dieses in der <a href="{0}/configure" target="_new">Systemkonfiguration</a> an.

View File

@ -20,7 +20,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
Maven\ Version.error.1=Hudson necesita saber donde está instalado Maven2.
Maven\ Version.error.1=Hudson necesita saber donde está instalado Maven2/3.
Maven\ Version.error.2=Configuraló en la pantalla de <a href="{0}/configure" target="_new">configuración del sistema</a>.
Root\ POM=Fichero POM raíz
Build=Proyecto

View File

@ -31,6 +31,6 @@ Build\ Settings=Configuration du build
Use\ private\ Maven\ repository=Utilise un repository Maven priv\u00E9
Use\ private\ maven\ repository=Utiliser un repository Maven privé
Goals\ and\ options=Goals et options
Maven\ Version.error.1=Hudson a besoin de savoir où Maven2 est installé.
Maven\ Version.error.1=Hudson a besoin de savoir où Maven2/3 est installé.
Maven\ Version.error.2=Veuillez le faire dans <a href="{0}/configure" target="_new">la configuration système</a>.
Build\ whenever\ a\ SNAPSHOT\ dependency\ is\ built=Lance un build à chaque fois qu''une dépendance SNAPSHOT est construite

View File

@ -22,7 +22,7 @@
Build=\u30D3\u30EB\u30C9
Maven\ Version=\u4F7F\u7528\u3059\u308BMaven
Maven\ Version.error.1=Maven2\u306E\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u5148\u3092\u8A2D\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
Maven\ Version.error.1=Maven2/3\u306E\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u5148\u3092\u8A2D\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
Maven\ Version.error.2=<a href="{0}/configure" target="_new">\u30B7\u30B9\u30C6\u30E0\u306E\u8A2D\u5B9A</a>\u3067\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002
Root\ POM=\u30EB\u30FC\u30C8POM
Goals\ and\ options=\u30B4\u30FC\u30EB\u3068\u30AA\u30D7\u30B7\u30E7\u30F3

View File

@ -20,5 +20,5 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
body=Byg et maven2 projekt. Hudson udnytter dine POM filer og reducerer herved \
body=Byg et maven2/3 projekt. Hudson udnytter dine POM filer og reducerer herved \
dramatisk behovet for konfiguration.

View File

@ -21,5 +21,5 @@
# THE SOFTWARE.
body=\
Dieses Profil baut ein Maven 2 Projekt. Hudson wertet dabei Ihre POM Dateien aus und \
Dieses Profil baut ein Maven 2/3 Projekt. Hudson wertet dabei Ihre POM Dateien aus und \
reduziert damit den Konfigurationsaufwand ganz erheblich.

View File

@ -20,4 +20,4 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
body=\u0394\u03B7\u03BC\u03B9\u03BF\u03C5\u03C1\u03B3\u03B9\u03B1 maven2 project. O Hudson \u03B1\u03BE\u03B9\u03BF\u03C0\u03BF\u03B9\u03B5\u03AF \u03C4\u03B1 \u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 POM \u03BA\u03B1\u03B9 \u03BC\u03B5\u03B9\u03CE\u03BD\u03B5\u03B9 \u03B4\u03C1\u03B1\u03BC\u03B1\u03C4\u03B9\u03BA\u03AC \u03C4\u03B7\u03BD \u03C0\u03B1\u03C1\u03B1\u03BC\u03B5\u03C4\u03C1\u03BF\u03C0\u03BF\u03B9\u03AE\u03C3\u03B7 \u03C0\u03BF\u03C5 \u03C7\u03C1\u03B5\u03B9\u03AC\u03B6\u03B5\u03C4\u03B1\u03B9
body=\u0394\u03B7\u03BC\u03B9\u03BF\u03C5\u03C1\u03B3\u03B9\u03B1 maven2/3 project. O Hudson \u03B1\u03BE\u03B9\u03BF\u03C0\u03BF\u03B9\u03B5\u03AF \u03C4\u03B1 \u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 POM \u03BA\u03B1\u03B9 \u03BC\u03B5\u03B9\u03CE\u03BD\u03B5\u03B9 \u03B4\u03C1\u03B1\u03BC\u03B1\u03C4\u03B9\u03BA\u03AC \u03C4\u03B7\u03BD \u03C0\u03B1\u03C1\u03B1\u03BC\u03B5\u03C4\u03C1\u03BF\u03C0\u03BF\u03B9\u03AE\u03C3\u03B7 \u03C0\u03BF\u03C5 \u03C7\u03C1\u03B5\u03B9\u03AC\u03B6\u03B5\u03C4\u03B1\u03B9

View File

@ -21,5 +21,5 @@
# THE SOFTWARE.
body=\
Ejecuta un proyecto maven2. Hudson es capaz de aprovechar la configuracion presente en los ficheros POM, reduciendo drásticamente la configuración.
Ejecuta un proyecto maven2/3. Hudson es capaz de aprovechar la configuracion presente en los ficheros POM, reduciendo drásticamente la configuración.

View File

@ -22,6 +22,6 @@
# OUTDATED
body=\
Construit un projet avec maven2. Hudson utilise directement vos fichiers POM \
Construit un projet avec maven2/3. Hudson utilise directement vos fichiers POM \
et diminue radicalement l''effort de configuration. Cette fonctionnalit\u00e9 est encore en b\u00eata mais elle est \
disponible afin d''obtenir vos retours.

View File

@ -20,4 +20,4 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
body=Effettua una build di un progetto maven2. Hudson sfrutta i file POM e riduce drasticamente la configurazione.
body=Effettua una build di un progetto maven2/3. Hudson sfrutta i file POM e riduce drasticamente la configurazione.

View File

@ -21,4 +21,4 @@
# THE SOFTWARE.
body=\
Maven2\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059\u3002Hudson\u306fPOM\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u5fc5\u8981\u306a\u60c5\u5831\u3092\u8aad\u307f\u53d6\u308b\u306e\u3067\u3001\u8a2d\u5b9a\u304c\u5fc5\u8981\u306a\u9805\u76ee\u306f\u3054\u304f\u308f\u305a\u304b\u3067\u3059\u3002
Maven2/3\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059\u3002Hudson\u306fPOM\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u5fc5\u8981\u306a\u60c5\u5831\u3092\u8aad\u307f\u53d6\u308b\u306e\u3067\u3001\u8a2d\u5b9a\u304c\u5fc5\u8981\u306a\u9805\u76ee\u306f\u3054\u304f\u308f\u305a\u304b\u3067\u3059\u3002

View File

@ -20,4 +20,4 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
body=Maven2 \uD504\uB85C\uC81D\uD2B8\uB97C \uBE4C\uB4DC\uD569\uB2C8\uB2E4. Hudson\uC740 POM \uD30C\uC77C\uC758 \uC774\uC810\uC744 \uAC00\uC9C0\uACE0 \uC788\uACE0 \uAE09\uACA9\uD788 \uC124\uC815\uC744 \uC904\uC785\uB2C8\uB2E4.
body=Maven2/3 \uD504\uB85C\uC81D\uD2B8\uB97C \uBE4C\uB4DC\uD569\uB2C8\uB2E4. Hudson\uC740 POM \uD30C\uC77C\uC758 \uC774\uC810\uC744 \uAC00\uC9C0\uACE0 \uC788\uACE0 \uAE09\uACA9\uD788 \uC124\uC815\uC744 \uC904\uC785\uB2C8\uB2E4.

View File

@ -20,4 +20,4 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
body=Bygg et Maven 2 prosjekt. Hudson tar fordel av dine POM (Project Object Model - Prosjekt Objekt Modell) filer og drastisk reduserer behovet for konfigurasjon.
body=Bygg et Maven 2/3 prosjekt. Hudson tar fordel av dine POM (Project Object Model - Prosjekt Objekt Modell) filer og drastisk reduserer behovet for konfigurasjon.

View File

@ -21,7 +21,7 @@
# THE SOFTWARE.
body=\
Bouw een maven2 project. Hudson maakt gebruikt van uw POM bestand wat \
Bouw een maven2/3 project. Hudson maakt gebruikt van uw POM bestand wat \
uw nood aan configuratie drastisch reduceert. Merk op dat deze functionaliteit \
nog steeds in ontwikkeling is, maar al reeds beschikbaar gesteld wordt om \
terugkoppeling te krijgen van gebruikers.

View File

@ -22,6 +22,6 @@
# OUTDATED
body=\
Construir um projeto maven2. Hudson tira vantagem de seus arquivos POM e \
Construir um projeto maven2/3. Hudson tira vantagem de seus arquivos POM e \
reduz drasticamente a configura\u00e7\u00e3o. Ainda \u00e9 um trabalho em progresso, mas \
diposto a aceitar feedback.

View File

@ -21,4 +21,4 @@
# THE SOFTWARE.
# OUTDATED
body=\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442 maven2. Hudson \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044E \u0438\u0437 \u043F\u0440\u043E\u0435\u043A\u0442\u043D\u044B\u0445 \u0444\u0430\u0439\u043B\u043E\u0432 POM, \u0447\u0442\u043E \u0443\u043C\u0435\u043D\u0448\u0438\u0442 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E\u0441\u0442\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F.
body=\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442 maven2/3. Hudson \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044E \u0438\u0437 \u043F\u0440\u043E\u0435\u043A\u0442\u043D\u044B\u0445 \u0444\u0430\u0439\u043B\u043E\u0432 POM, \u0447\u0442\u043E \u0443\u043C\u0435\u043D\u0448\u0438\u0442 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E\u0441\u0442\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F.

View File

@ -20,4 +20,4 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
body=Bygg ett maven2 projekt. Hudson utnyttjar dina POM filer och kommer drastiskt minska behovet av konfiguration.
body=Bygg ett maven2/3 projekt. Hudson utnyttjar dina POM filer och kommer drastiskt minska behovet av konfiguration.

View File

@ -21,4 +21,4 @@
# THE SOFTWARE.
# OUTDATED
body=Maven2\ projesi\ yap\u0131land\u0131r.\ Hudson,\ POM\ dosyalar\u0131n\u0131z\u0131n\ avantajlar\u0131n\u0131\ kullan\u0131r\ ve\ konfig\u00fcrasyonu\ inan\u0131lmaz\ derecede\ azalt\u0131r.\ Hala\ \u00fczerinde\ \u00e7al\u0131\u015fma\ devam\ ediyor,\ dolay\u0131s\u0131yla geri\ bildirimler\ daima faydal\u0131 olacakt\u0131r.
body=Maven2/3\ projesi\ yap\u0131land\u0131r.\ Hudson,\ POM\ dosyalar\u0131n\u0131z\u0131n\ avantajlar\u0131n\u0131\ kullan\u0131r\ ve\ konfig\u00fcrasyonu\ inan\u0131lmaz\ derecede\ azalt\u0131r.\ Hala\ \u00fczerinde\ \u00e7al\u0131\u015fma\ devam\ ediyor,\ dolay\u0131s\u0131yla geri\ bildirimler\ daima faydal\u0131 olacakt\u0131r.

View File

@ -21,4 +21,4 @@
# THE SOFTWARE.
body=\
\u6784\u5efa\u4e00\u4e2amaven2\u9879\u76ee.Hudson\u5229\u7528\u4f60\u7684POM\u6587\u4ef6,\u8fd9\u6837\u53ef\u4ee5\u5927\u5927\u51cf\u8f7b\u6784\u5efa\u914d\u7f6e.
\u6784\u5efa\u4e00\u4e2amaven2/3\u9879\u76ee.Hudson\u5229\u7528\u4f60\u7684POM\u6587\u4ef6,\u8fd9\u6837\u53ef\u4ee5\u5927\u5927\u51cf\u8f7b\u6784\u5efa\u914d\u7f6e.

View File

@ -30,7 +30,7 @@ MavenBuilder.Waiting=Waiting for Hudson to finish collecting data
MavenModule.Pronoun=Module
MavenModuleSet.DiplayName=Build a maven2 project
MavenModuleSet.DiplayName=Build a maven2/3 project
MavenModuleSetBuild.DiscoveredModule=Discovered a new module {0} {1}
MavenModuleSetBuild.FailedToParsePom=Failed to parse POMs
@ -40,7 +40,7 @@ MavenModuleSetBuild.NoMavenInstall=A Maven installation needs to be available fo
MavenProbeAction.DisplayName=Monitor Maven Process
MavenProcessFactory.ClassWorldsNotFound=No classworlds*.jar found in {0} -- Is this a valid maven2 directory?
MavenProcessFactory.ClassWorldsNotFound=No classworlds*.jar found in {0} -- Is this a valid maven2/3 directory?
MavenRedeployer.DisplayName=Deploy to Maven repository
ProcessCache.Reusing=Reusing existing maven process

View File

@ -29,7 +29,7 @@ MavenBuilder.Aborted=Afbrudt
MavenBuilder.Failed=Maven stoppede med en fejl.
MavenProbeAction.DisplayName=Overv\u00e5g Mavenproces
MavenProcessFactory.ClassWorldsNotFound=Ingen classworlds*.jar fundet i {0} -- Er dette et gyldigt maven2 direktorie?
MavenModuleSet.DiplayName=Byg et maven2 projekt
MavenModuleSet.DiplayName=Byg et maven2/3 projekt
MavenModule.Pronoun=Modul
MavenBuild.FailedEarlier=Bygget fejler f\u00f8r det n\u00e5r til dette modul
MavenModuleSetBuild.NoSuchPOMFile=Ingen fil kaldet {0}\nM\u00e5ske mangler du at specificere den korrekte POM fil placering i projekt konfigurationen?

View File

@ -30,7 +30,7 @@ MavenBuilder.Waiting=Esperando a que Hudson finalize de recopilar datos
MavenModule.Pronoun=Modulo
MavenModuleSet.DiplayName=Crear un proyecto maven2
MavenModuleSet.DiplayName=Crear un proyecto maven2/3
MavenModuleSetBuild.DiscoveredModule=Se ha descubierto un nuevo módulo {0} {1}
MavenModuleSetBuild.FailedToParsePom=Error al analizar el fichero POM

View File

@ -29,7 +29,7 @@ MavenBuilder.Waiting=En attente qu''Hudson finisse de r
MavenModule.Pronoun=Module
MavenModuleSet.DiplayName=Construire un projet maven2
MavenModuleSet.DiplayName=Construire un projet maven2/3
MavenModuleSetBuild.DiscoveredModule=Un nouveau module {0} {1} a été trouvé
MavenModuleSetBuild.FailedToParsePom=Echec à la lecture des POMs
@ -37,7 +37,7 @@ MavenModuleSetBuild.NoSuchFile=Pas de fichier {0}\nAvez-vous sp
MavenProbeAction.DisplayName=Surveiller un process Maven
MavenProcessFactory.ClassWorldsNotFound=Pas de fichier classworlds*.jar trouvé dans {0} -- Est-ce un répertoire maven2 valide?
MavenProcessFactory.ClassWorldsNotFound=Pas de fichier classworlds*.jar trouvé dans {0} -- Est-ce un répertoire maven2/3 valide?
MavenRedeployer.DisplayName=Déployer vers un repository Maven
ProcessCache.Reusing=Réutilisation du process Maven existant

View File

@ -30,7 +30,7 @@ MavenBuilder.Waiting=Hudson\u304c\u30c7\u30fc\u30bf\u53ce\u96c6\u3092\u5b8c\u4e8
MavenModule.Pronoun=\u30e2\u30b8\u30e5\u30fc\u30eb
MavenModuleSet.DiplayName=Maven2\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u30d3\u30eb\u30c9
MavenModuleSet.DiplayName=Maven2/3\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u30d3\u30eb\u30c9
MavenModuleSetBuild.DiscoveredModule=\u65b0\u898f\u30e2\u30b8\u30e5\u30fc\u30eb {0} {1} \u3092\u767a\u898b
MavenModuleSetBuild.FailedToParsePom=POM\u306e\u89e3\u6790\u306b\u5931\u6557

View File

@ -30,7 +30,7 @@ MavenBuilder.Waiting=Wachtend to Hudson het verzamelen van gegevens be\u00EBindi
MavenModule.Pronoun=Module
MavenModuleSet.DiplayName=Bouw een maven2 project
MavenModuleSet.DiplayName=Bouw een maven2 p/3roject
MavenModuleSetBuild.DiscoveredModule= Een nieuwe module {0} {1} werd ontdekt.
MavenModuleSetBuild.FailedToParsePom=Het lezen van de POMs is gefaald.

View File

@ -29,7 +29,7 @@ MavenBuilder.Waiting=Aguardando Hudson terminar de coletar dados
MavenModule.Pronoun=M\u00f3dulo
MavenModuleSet.DiplayName=Construir um projeto maven2
MavenModuleSet.DiplayName=Construir um projeto maven2/3
MavenModuleSetBuild.DiscoveredModule=Descoberto um novo m\u00f3dulo {0} {1}
MavenModuleSetBuild.FailedToParsePom=Falhou ao analisar POMs

View File

@ -29,7 +29,7 @@ MavenBuilder.Waiting=\u041e\u0436\u0438\u0434\u0430\u044e \u043f\u043e\u043a\u04
MavenModule.Pronoun=\u041c\u043e\u0434\u0443\u043b\u044c
MavenModuleSet.DiplayName=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 maven2
MavenModuleSet.DiplayName=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 maven2/3
MavenModuleSetBuild.DiscoveredModule=\u041d\u0430\u0439\u0434\u0435\u043d \u043d\u043e\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c {0} {1}
MavenModuleSetBuild.FailedToParsePom=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c POM \u0444\u0430\u0439\u043b\u044b

View File

@ -30,7 +30,7 @@ MavenBuilder.Waiting=Hudson''\u0131n bilgi toplamay\u0131 bitirmesi bekleniyor
MavenModule.Pronoun=Mod\u00fcl
MavenModuleSet.DiplayName=Maven2 projesi yap\u0131land\u0131r
MavenModuleSet.DiplayName=Maven2/3 projesi yap\u0131land\u0131r
MavenModuleSetBuild.DiscoveredModule={0} {1} olarak yeni bir mod\u00fcl bulundu
MavenModuleSetBuild.FailedToParsePom=POMlar\u0131 ayr\u0131\u015ft\u0131r\u0131rken hata ile kar\u015f\u0131la\u015f\u0131ld\u0131

View File

@ -30,7 +30,7 @@ MavenBuilder.Waiting=Waiting for Hudson to finish collecting data
MavenModule.Pronoun=\u6a21\u5757
MavenModuleSet.DiplayName=\u6784\u5efa\u4e00\u4e2amaven2\u9879\u76ee
MavenModuleSet.DiplayName=\u6784\u5efa\u4e00\u4e2amaven2/3\u9879\u76ee
MavenModuleSetBuild.DiscoveredModule=Discovered a new module {0} {1}
MavenModuleSetBuild.FailedToParsePom=Failed to parse POMs

5
maven3-agent/.gitignore vendored Executable file
View File

@ -0,0 +1,5 @@
.settings
.project
target
.classpath
build

38
maven3-agent/pom.xml Executable file
View File

@ -0,0 +1,38 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.392-SNAPSHOT</version>
</parent>
<artifactId>maven3-agent</artifactId>
<name>Hudson Maven3 CLI Agent</name>
<dependencies>
<dependency>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>maven3-interceptor</artifactId>
<scope>provided</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-classworlds</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-inject-plexus</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,177 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Olivier Lamy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson.maven3.agent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.codehaus.plexus.classworlds.launcher.Launcher;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
/**
* Entry point for launching Maven 3 and Hudson remoting in the same VM, in the
* classloader layout that Maven expects.
*
* <p>
* The actual Maven execution will be started by the program sent through
* remoting.
* </p>
*
* @author Kohsuke Kawaguchi
* @author Olivier Lamy
*/
public class Maven3Main {
/**
* Used to pass the classworld instance to the code running inside the
* remoting system.
*/
private static Launcher launcher;
public static void main(String[] args) throws Exception {
main(new File(args[0]), new File(args[1]),new File(args[2]),
Integer.parseInt(args[3]));
}
/**
*
* @param m2Home
* Maven2 installation. This is where we find Maven jars that
* we'll run.
* @param remotingJar
* Hudson's remoting.jar that we'll load.
* @param interceptorJar
* maven-listener.jar that we'll load.
* @param tcpPort
* TCP socket that the launching Hudson will be listening to.
* This is used for the remoting communication.
* @param projectBuildLaunch
* launch the projectBuilder and not a mavenExecution
*/
public static void main(File m2Home, File remotingJar, File interceptorJar,
int tcpPort) throws Exception {
// Unix master with Windows slave ends up passing path in Unix format,
// so convert it to Windows format now so that no one chokes with the
// path format later.
try {
m2Home = m2Home.getCanonicalFile();
} catch (IOException e) {
// ignore. We'll check the error later if m2Home exists anyway
}
if (!m2Home.exists()) {
System.err.println("No such directory exists: " + m2Home);
System.exit(1);
}
versionCheck();
// expose variables used in the classworlds configuration
System.setProperty("maven.home", m2Home.getPath());
System.setProperty("maven3.interceptor", (interceptorJar != null ? interceptorJar
: interceptorJar).getPath());
// load the default realms
launcher = new Launcher();
launcher.setSystemClassLoader(Maven3Main.class.getClassLoader());
launcher.configure(Maven3Main.class
.getResourceAsStream("classworlds.conf"));
// create a realm for loading remoting subsystem.
// this needs to be able to see maven.
ClassRealm remoting = launcher.getWorld().newRealm( "hudson-remoting", launcher.getSystemClassLoader() );
remoting.setParentRealm(launcher.getWorld().getRealm("plexus.core"));
remoting.addURL(remotingJar.toURI().toURL());
final Socket s = new Socket((String) null, tcpPort);
Class remotingLauncher = remoting.loadClass("hudson.remoting.Launcher");
remotingLauncher.getMethod("main",
new Class[] { InputStream.class, OutputStream.class }).invoke(
null,
new Object[] {
// do partial close, since socket.getInputStream and
// getOutputStream doesn't do it by
new BufferedInputStream(new FilterInputStream(s
.getInputStream()) {
public void close() throws IOException {
s.shutdownInput();
}
}),
new BufferedOutputStream(new RealFilterOutputStream(s
.getOutputStream()) {
public void close() throws IOException {
s.shutdownOutput();
}
}) });
System.exit(0);
}
/**
* Called by the code in remoting to launch.
*/
public static int launch(String[] args) throws Exception {
try {
launcher.launch(args);
} catch (Throwable e)
{
e.printStackTrace();
throw new Exception( e );
}
return launcher.getExitCode();
}
/**
* Makes sure that this is Java5 or later.
*/
private static void versionCheck() {
String v = System.getProperty("java.class.version");
if (v != null) {
try {
if (Float.parseFloat(v) < 49.0) {
System.err
.println("Native maven support requires Java 1.5 or later, but this Maven is using "
+ System.getProperty("java.home"));
System.err.println("Please use the freestyle project.");
System.exit(1);
}
} catch (NumberFormatException e) {
// couldn't check.
}
}
}
}

View File

@ -0,0 +1,51 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson.maven3.agent;
import java.io.OutputStream;
import java.io.IOException;
import java.io.FilterOutputStream;
/**
* JDK's {@link FilterOutputStream} has some real issues.
*
* @author Kohsuke Kawaguchi
*/
class RealFilterOutputStream extends FilterOutputStream {
public RealFilterOutputStream(OutputStream core) {
super(core);
}
public void write(byte[] b) throws IOException {
out.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
}
public void close() throws IOException {
out.close();
}
}

View File

@ -0,0 +1,10 @@
#
# mostly copied as-is from $MAVEN_HOME/bin/m2.conf
#
main is org.jvnet.hudson.maven3.launcher.Maven3Launcher from plexus.core
set maven.home default ${user.home}/m2
[plexus.core]
load ${maven3.interceptor}
load ${maven.home}/lib/*.jar

5
maven3-interceptor/.gitignore vendored Executable file
View File

@ -0,0 +1,5 @@
.settings
.project
target
.classpath
build

55
maven3-interceptor/pom.xml Executable file
View File

@ -0,0 +1,55 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.392-SNAPSHOT</version>
</parent>
<artifactId>maven3-interceptor</artifactId>
<name>Hudson Maven3 Interceptor</name>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-aether-provider</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-inject-plexus</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-metadata</artifactId>
<version>1.5.4</version>
<executions>
<execution>
<goals>
<goal>generate-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,791 @@
package org.apache.maven.cli;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.ParseException;
import org.apache.maven.execution.DefaultMavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequestPopulationException;
import org.apache.maven.execution.MavenExecutionRequestPopulator;
import org.apache.maven.lifecycle.internal.LifecycleWeaveBuilder;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.properties.internal.EnvironmentUtils;
import org.apache.maven.repository.internal.MavenRepositorySystemSession;
import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuilder;
import org.apache.maven.settings.building.SettingsBuildingException;
import org.apache.maven.settings.building.SettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuildingResult;
import org.apache.maven.settings.building.SettingsProblem;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.codehaus.plexus.util.StringUtils;
import org.sonatype.aether.impl.internal.EnhancedLocalRepositoryManager;
import org.sonatype.aether.transfer.TransferListener;
import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
/**
* Most of code is coming from asf svn repo waiting before having available
* @author Olivier Lamy
*/
@Component( role = MavenExecutionRequestBuilder.class)
public class DefaultMavenExecutionRequestBuilder
implements MavenExecutionRequestBuilder, Initializable
{
@Requirement
private SettingsBuilder settingsBuilder;
@Requirement
private MavenExecutionRequestPopulator executionRequestPopulator;
@Requirement
private Logger plexusLogger;
@Requirement
private ModelProcessor modelProcessor;
@Requirement
private PlexusContainer plexusContainer;
private DefaultSecDispatcher dispatcher;
public void initialize()
throws InitializationException
{
try
{
dispatcher = (DefaultSecDispatcher) plexusContainer.lookup( SecDispatcher.class, "maven" );
}
catch ( ComponentLookupException e )
{
throw new InitializationException( e.getMessage(), e );
}
}
/**
* @throws MavenExecutionRequestPopulationException
* @see org.jvnet.hudson.maven3.MavenExecutionRequestBuilder.MavenExecutionRequestsBuilder#getMavenExecutionRequest(java.lang.String[])
*/
public MavenExecutionRequest getMavenExecutionRequest( String[] args, PrintStream printStream )
throws MavenExecutionRequestPopulationException, SettingsBuildingException,
MavenExecutionRequestsBuilderException
{
try
{
CliRequest cliRequest = new CliRequest( args, null );
initialize( cliRequest, printStream );
// Need to process cli options first to get possible logging options
cli( cliRequest );
logging( cliRequest );
commands( cliRequest );
properties( cliRequest );
// we are in a container so no need
//container( cliRequest );
settings( cliRequest );
populateRequest( cliRequest );
encryption( cliRequest );
MavenExecutionRequest request = executionRequestPopulator.populateDefaults( cliRequest.request );
// TODO move this in ASF sources ?
if (request.getProjectBuildingRequest().getRepositorySession()== null)
{
MavenRepositorySystemSession session = new MavenRepositorySystemSession();
if (session.getLocalRepositoryManager() == null)
{
session.setLocalRepositoryManager( new EnhancedLocalRepositoryManager( request.getLocalRepositoryPath() ) );
}
request.getProjectBuildingRequest().setRepositorySession( session );
}
return request;
}
catch ( Exception e )
{
throw new MavenExecutionRequestsBuilderException( e.getMessage(), e );
}
}
static File resolveFile( File file, String workingDirectory )
{
if ( file == null )
{
return null;
}
else if ( file.isAbsolute() )
{
return file;
}
else if ( file.getPath().startsWith( File.separator ) )
{
// drive-relative Windows path
return file.getAbsoluteFile();
}
else
{
return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
}
}
private void initialize( CliRequest cliRequest, PrintStream printStream )
{
if ( cliRequest.stdout == null )
{
cliRequest.stdout = System.out;
}
if ( cliRequest.stderr == null )
{
cliRequest.stderr = System.err;
}
if ( cliRequest.logger == null )
{
cliRequest.logger = new PrintStreamLogger( cliRequest.stdout );
}
else
{
cliRequest.logger.setStream( cliRequest.stdout );
}
if ( cliRequest.workingDirectory == null )
{
cliRequest.workingDirectory = System.getProperty( "user.dir" );
}
//
// Make sure the Maven home directory is an absolute path to save us from confusion with say drive-relative
// Windows paths.
//
String mavenHome = System.getProperty( "maven.home" );
if ( mavenHome != null )
{
System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
}
}
private void cli( CliRequest cliRequest )
throws Exception
{
CLIManager cliManager = new CLIManager();
try
{
cliRequest.commandLine = cliManager.parse( cliRequest.args );
}
catch ( ParseException e )
{
cliRequest.stderr.println( "Unable to parse command line options: " + e.getMessage() );
cliManager.displayHelp( cliRequest.stdout );
throw e;
}
// TODO: these should be moved out of here. Wrong place.
//
if ( cliRequest.commandLine.hasOption( CLIManager.HELP ) )
{
cliManager.displayHelp( cliRequest.stdout );
throw new MavenCli.ExitException( 0 );
}
if ( cliRequest.commandLine.hasOption( CLIManager.VERSION ) )
{
CLIReportingUtils.showVersion( cliRequest.stdout );
throw new MavenCli.ExitException( 0 );
}
}
private void logging( CliRequest cliRequest )
{
cliRequest.debug = cliRequest.commandLine.hasOption( CLIManager.DEBUG );
cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption( CLIManager.QUIET );
cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.ERRORS );
if ( cliRequest.debug )
{
cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_DEBUG );
}
else if ( cliRequest.quiet )
{
// TODO: we need to do some more work here. Some plugins use sys out or log errors at info level.
// Ideally, we could use Warn across the board
cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_ERROR );
// TODO:Additionally, we can't change the mojo level because the component key includes the version and
// it isn't known ahead of time. This seems worth changing.
}
else
{
cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_INFO );
}
plexusLogger.setThreshold( cliRequest.request.getLoggingLevel() );
if ( cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
{
File logFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.LOG_FILE ) );
logFile = resolveFile( logFile, cliRequest.workingDirectory );
try
{
cliRequest.fileStream = new PrintStream( logFile );
cliRequest.logger.setStream( cliRequest.fileStream );
}
catch ( FileNotFoundException e )
{
cliRequest.stderr.println( e );
cliRequest.logger.setStream( cliRequest.stdout );
}
}
else
{
cliRequest.logger.setStream( cliRequest.stdout );
}
cliRequest.request.setExecutionListener( new ExecutionEventLogger( cliRequest.logger ) );
}
private void commands( CliRequest cliRequest )
{
if ( cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.SHOW_VERSION ) )
{
CLIReportingUtils.showVersion( cliRequest.stdout );
}
if ( cliRequest.showErrors )
{
cliRequest.logger.info( "Error stacktraces are turned on." );
}
//
// TODO: move checksum policies to
//
if ( MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
{
cliRequest.logger.info( "Disabling strict checksum verification on all artifact downloads." );
}
else if ( MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
{
cliRequest.logger.info( "Enabling strict checksum verification on all artifact downloads." );
}
}
private void properties( CliRequest cliRequest )
{
populateProperties( cliRequest.commandLine, cliRequest.systemProperties, cliRequest.userProperties );
}
// ----------------------------------------------------------------------
// System properties handling
// ----------------------------------------------------------------------
static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
{
EnvironmentUtils.addEnvVars( systemProperties );
// ----------------------------------------------------------------------
// Options that are set on the command line become system properties
// and therefore are set in the session properties. System properties
// are most dominant.
// ----------------------------------------------------------------------
if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
{
String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
if ( defStrs != null )
{
for ( int i = 0; i < defStrs.length; ++i )
{
setCliProperty( defStrs[i], userProperties );
}
}
}
systemProperties.putAll( System.getProperties() );
}
private static void setCliProperty( String property, Properties properties )
{
String name;
String value;
int i = property.indexOf( "=" );
if ( i <= 0 )
{
name = property.trim();
value = "true";
}
else
{
name = property.substring( 0, i ).trim();
value = property.substring( i + 1 );
}
properties.setProperty( name, value );
// ----------------------------------------------------------------------
// I'm leaving the setting of system properties here as not to break
// the SystemPropertyProfileActivator. This won't harm embedding. jvz.
// ----------------------------------------------------------------------
System.setProperty( name, value );
}
private void settings( CliRequest cliRequest )
throws Exception
{
File userSettingsFile;
if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
{
userSettingsFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS ) );
userSettingsFile = resolveFile( userSettingsFile, cliRequest.workingDirectory );
if ( !userSettingsFile.isFile() )
{
throw new FileNotFoundException( "The specified user settings file does not exist: " + userSettingsFile );
}
}
else
{
userSettingsFile = MavenCli.DEFAULT_USER_SETTINGS_FILE;
}
cliRequest.logger.debug( "Reading user settings from " + userSettingsFile );
File globalSettingsFile;
if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) )
{
globalSettingsFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) );
globalSettingsFile = resolveFile( globalSettingsFile, cliRequest.workingDirectory );
if ( !globalSettingsFile.isFile() )
{
throw new FileNotFoundException( "The specified global settings file does not exist: "
+ globalSettingsFile );
}
}
else
{
globalSettingsFile = MavenCli.DEFAULT_GLOBAL_SETTINGS_FILE;
}
cliRequest.logger.debug( "Reading global settings from " + globalSettingsFile );
cliRequest.request.setGlobalSettingsFile( globalSettingsFile );
cliRequest.request.setUserSettingsFile( userSettingsFile );
SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
settingsRequest.setGlobalSettingsFile( globalSettingsFile );
settingsRequest.setUserSettingsFile( userSettingsFile );
settingsRequest.setSystemProperties( cliRequest.systemProperties );
settingsRequest.setUserProperties( cliRequest.userProperties );
SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
executionRequestPopulator.populateFromSettings( cliRequest.request, settingsResult.getEffectiveSettings() );
if ( !settingsResult.getProblems().isEmpty() && cliRequest.logger.isWarnEnabled() )
{
cliRequest.logger.warn( "" );
cliRequest.logger.warn( "Some problems were encountered while building the effective settings" );
for ( SettingsProblem problem : settingsResult.getProblems() )
{
cliRequest.logger.warn( problem.getMessage() + " @ " + problem.getLocation() );
}
cliRequest.logger.warn( "" );
}
}
private MavenExecutionRequest populateRequest( CliRequest cliRequest )
{
MavenExecutionRequest request = cliRequest.request;
CommandLine commandLine = cliRequest.commandLine;
String workingDirectory = cliRequest.workingDirectory;
boolean debug = cliRequest.debug;
boolean quiet = cliRequest.quiet;
boolean showErrors = cliRequest.showErrors;
String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
for ( String deprecatedOption : deprecatedOptions )
{
if ( commandLine.hasOption( deprecatedOption ) )
{
cliRequest.stdout.println( "[WARNING] Command line option -" + deprecatedOption
+ " is deprecated and will be removed in future Maven versions." );
}
}
// ----------------------------------------------------------------------
// Now that we have everything that we need we will fire up plexus and
// bring the maven component to life for use.
// ----------------------------------------------------------------------
if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
{
request.setInteractiveMode( false );
}
boolean noSnapshotUpdates = false;
if ( commandLine.hasOption( CLIManager.SUPRESS_SNAPSHOT_UPDATES ) )
{
noSnapshotUpdates = true;
}
// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
@SuppressWarnings("unchecked")
List<String> goals = commandLine.getArgList();
boolean recursive = true;
// this is the default behavior.
String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
{
recursive = false;
}
if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
{
reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
}
else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
{
reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
}
else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
{
reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
}
if ( commandLine.hasOption( CLIManager.OFFLINE ) )
{
request.setOffline( true );
}
boolean updateSnapshots = false;
if ( commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
{
updateSnapshots = true;
}
String globalChecksumPolicy = null;
if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
{
globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
}
else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
{
globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
}
File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();
// ----------------------------------------------------------------------
// Profile Activation
// ----------------------------------------------------------------------
List<String> activeProfiles = new ArrayList<String>();
List<String> inactiveProfiles = new ArrayList<String>();
if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
{
String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
if ( profileOptionValues != null )
{
for ( int i = 0; i < profileOptionValues.length; ++i )
{
StringTokenizer profileTokens = new StringTokenizer( profileOptionValues[i], "," );
while ( profileTokens.hasMoreTokens() )
{
String profileAction = profileTokens.nextToken().trim();
if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
{
inactiveProfiles.add( profileAction.substring( 1 ) );
}
else if ( profileAction.startsWith( "+" ) )
{
activeProfiles.add( profileAction.substring( 1 ) );
}
else
{
activeProfiles.add( profileAction );
}
}
}
}
}
TransferListener transferListener;
if ( quiet )
{
transferListener = new QuietMavenTransferListener( );
}
else if ( request.isInteractiveMode() )
{
transferListener = new ConsoleMavenTransferListener( cliRequest.stdout );
}
else
{
transferListener = new BatchModeMavenTransferListener( cliRequest.stdout );
}
//transferListener. .setShowChecksumEvents( false );
String alternatePomFile = null;
if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
{
alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
}
int loggingLevel;
if ( debug )
{
loggingLevel = MavenExecutionRequest.LOGGING_LEVEL_DEBUG;
}
else if ( quiet )
{
// TODO: we need to do some more work here. Some plugins use sys out or log errors at info level.
// Ideally, we could use Warn across the board
loggingLevel = MavenExecutionRequest.LOGGING_LEVEL_ERROR;
// TODO:Additionally, we can't change the mojo level because the component key includes the version and
// it isn't known ahead of time. This seems worth changing.
}
else
{
loggingLevel = MavenExecutionRequest.LOGGING_LEVEL_INFO;
}
File userToolchainsFile;
if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
{
userToolchainsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
userToolchainsFile = resolveFile( userToolchainsFile, workingDirectory );
}
else
{
userToolchainsFile = MavenCli.DEFAULT_USER_TOOLCHAINS_FILE;
}
request.setBaseDirectory( baseDirectory ).setGoals( goals ).setSystemProperties( cliRequest.systemProperties )
.setUserProperties( cliRequest.userProperties ).setReactorFailureBehavior( reactorFailureBehaviour ) // default: fail fast
.setRecursive( recursive ) // default: true
.setShowErrors( showErrors ) // default: false
.addActiveProfiles( activeProfiles ) // optional
.addInactiveProfiles( inactiveProfiles ) // optional
.setLoggingLevel( loggingLevel ) // default: info
.setTransferListener( transferListener ) // default: batch mode which goes along with interactive
.setUpdateSnapshots( updateSnapshots ) // default: false
.setNoSnapshotUpdates( noSnapshotUpdates ) // default: false
.setGlobalChecksumPolicy( globalChecksumPolicy ) // default: warn
.setUserToolchainsFile( userToolchainsFile );
if ( alternatePomFile != null )
{
File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
request.setPom( pom );
}
else
{
File pom = modelProcessor.locatePom( baseDirectory );
if ( pom.isFile() )
{
request.setPom( pom );
}
}
if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
{
request.setBaseDirectory( request.getPom().getParentFile() );
}
if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
{
request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
}
if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
{
String projectList = commandLine.getOptionValue( CLIManager.PROJECT_LIST );
String[] projects = StringUtils.split( projectList, "," );
request.setSelectedProjects( Arrays.asList( projects ) );
}
if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) && !commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
{
request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
}
else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE )
&& commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
{
request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
}
else if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
&& commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
{
request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
}
String localRepoProperty = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
if ( localRepoProperty == null )
{
localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
}
if ( localRepoProperty != null )
{
request.setLocalRepositoryPath( localRepoProperty );
}
final String threadConfiguration = commandLine.hasOption( CLIManager.THREADS ) ? commandLine
.getOptionValue( CLIManager.THREADS ) : request.getSystemProperties()
.getProperty( MavenCli.THREADS_DEPRECATED ); // TODO: Remove this setting. Note that the int-tests use it
if ( threadConfiguration != null )
{
request.setPerCoreThreadCount( threadConfiguration.contains( "C" ) );
if ( threadConfiguration.contains( "W" ) )
{
LifecycleWeaveBuilder.setWeaveMode( request.getUserProperties() );
}
request.setThreadCount( threadConfiguration.replace( "C", "" ).replace( "W", "" ).replace( "auto", "" ) );
}
return request;
}
private void encryption( CliRequest cliRequest )
throws Exception
{
if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
{
String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );
DefaultPlexusCipher cipher = new DefaultPlexusCipher();
cliRequest.stdout.println( cipher.encryptAndDecorate( passwd,
DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );
throw new MavenCli.ExitException( 0 );
}
else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
{
String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );
String configurationFile = dispatcher.getConfigurationFile();
if ( configurationFile.startsWith( "~" ) )
{
configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
}
String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
String master = null;
SettingsSecurity sec = SecUtil.read( file, true );
if ( sec != null )
{
master = sec.getMaster();
}
if ( master == null )
{
throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
}
DefaultPlexusCipher cipher = new DefaultPlexusCipher();
String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
cliRequest.stdout.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
throw new MavenCli.ExitException( 0 );
}
}
static class CliRequest
{
String[] args;
CommandLine commandLine;
PrintStream stdout;
PrintStream stderr;
ClassWorld classWorld;
String workingDirectory;
boolean debug;
boolean quiet;
boolean showErrors = true;
PrintStream fileStream;
Properties userProperties = new Properties();
Properties systemProperties = new Properties();
MavenExecutionRequest request;
PrintStreamLogger logger;
CliRequest( String[] args, ClassWorld classWorld )
{
this.args = args;
this.classWorld = classWorld;
this.request = new DefaultMavenExecutionRequest();
}
}
}

View File

@ -0,0 +1,36 @@
package org.apache.maven.cli;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.PrintStream;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequestPopulationException;
import org.apache.maven.settings.building.SettingsBuildingException;
/**
* @author Olivier Lamy
* @since
*/
public interface MavenExecutionRequestBuilder
{
MavenExecutionRequest getMavenExecutionRequest( String[] args, PrintStream printStream )
throws MavenExecutionRequestPopulationException, SettingsBuildingException, MavenExecutionRequestsBuilderException;
}

View File

@ -0,0 +1,33 @@
package org.apache.maven.cli;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @author Olivier Lamy
* @since
*/
public class MavenExecutionRequestsBuilderException
extends Exception
{
public MavenExecutionRequestsBuilderException(String message, Throwable exception)
{
super( message, exception );
}
}

View File

@ -0,0 +1,101 @@
package org.jvnet.hudson.maven3.launcher;
/*
* Olivier Lamy
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.Maven;
import org.apache.maven.cli.MavenExecutionRequestBuilder;
import org.apache.maven.cli.MavenLoggerManager;
import org.apache.maven.cli.PrintStreamLogger;
import org.apache.maven.execution.ExecutionListener;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;
import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.DefaultContainerConfiguration;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.jvnet.hudson.maven3.listeners.HudsonMavenExecutionResult;
/**
* @author olamy
*
*/
public class Maven3Launcher {
private static HudsonMavenExecutionResult hudsonMavenExecutionResult;
private static ExecutionListener mavenExecutionListener;
public static ExecutionListener getMavenExecutionListener() {
return mavenExecutionListener;
}
public static void setMavenExecutionListener( ExecutionListener listener ) {
mavenExecutionListener = listener;
}
public static HudsonMavenExecutionResult getMavenExecutionResult() {
return hudsonMavenExecutionResult;
}
public static void setMavenExecutionResult( HudsonMavenExecutionResult result ) {
hudsonMavenExecutionResult = result;
}
public static int main( String[] args ) throws Exception {
ClassLoader orig = Thread.currentThread().getContextClassLoader();
try {
ClassRealm containerRealm = (ClassRealm) Thread.currentThread().getContextClassLoader();
ContainerConfiguration cc = new DefaultContainerConfiguration().setName( "maven" )
.setRealm( containerRealm );
DefaultPlexusContainer container = new DefaultPlexusContainer( cc );
MavenLoggerManager mavenLoggerManager = new MavenLoggerManager( new PrintStreamLogger( System.out ) );
container.setLoggerManager( mavenLoggerManager );
Maven maven = (Maven) container.lookup( "org.apache.maven.Maven", "default" );
MavenExecutionRequest request = getMavenExecutionRequest( args, container );
MavenExecutionResult result = maven.execute( request );
hudsonMavenExecutionResult = new HudsonMavenExecutionResult( result );
// we don't care about cli mavenExecutionResult will be study in the the plugin
return 0;// cli.doMain( args, null );
} catch ( ComponentLookupException e ) {
throw new Exception( e.getMessage(), e );
} finally {
Thread.currentThread().setContextClassLoader( orig );
}
}
private static MavenExecutionRequest getMavenExecutionRequest( String[] args, DefaultPlexusContainer container ) throws Exception {
MavenExecutionRequestBuilder mavenExecutionRequestBuilder = container
.lookup( MavenExecutionRequestBuilder.class );
MavenExecutionRequest request = mavenExecutionRequestBuilder.getMavenExecutionRequest( args, System.out );
if ( mavenExecutionListener != null ) {
request.setExecutionListener( mavenExecutionListener );
}
return request;
}
}

View File

@ -0,0 +1,85 @@
package org.jvnet.hudson.maven3.listeners;
/*
* Olivier Lamy
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.execution.BuildSummary;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.project.MavenProject;
/**
* @author Olivier Lamy
* @since
*/
public class HudsonMavenExecutionResult implements Serializable
{
List<Throwable> throwables = new ArrayList<Throwable>();
List<MavenProjectInfo> mavenProjectInfos = new ArrayList<MavenProjectInfo>();
public HudsonMavenExecutionResult(MavenExecutionResult mavenExecutionResult)
{
if (mavenExecutionResult == null)
{
return;
}
throwables = mavenExecutionResult.getExceptions();
List<MavenProject> mavenProjects = mavenExecutionResult.getTopologicallySortedProjects();
if (mavenProjects != null)
{
for (MavenProject mavenProject : mavenProjects)
{
MavenProjectInfo mavenProjectInfo = new MavenProjectInfo( mavenProject );
mavenProjectInfos.add( mavenProjectInfo );
BuildSummary buildSummary = mavenExecutionResult.getBuildSummary( mavenProject );
// NPE free : looks to have null here when the projects is not finished ie tests failures
if ( buildSummary != null )
{
mavenProjectInfo.setBuildTime( buildSummary.getTime() );
}
}
}
}
public List<Throwable> getThrowables()
{
return throwables;
}
public void setThrowables( List<Throwable> throwables )
{
this.throwables = throwables;
}
public List<MavenProjectInfo> getMavenProjectInfos()
{
return mavenProjectInfos;
}
public void setMavenProjectInfos( List<MavenProjectInfo> mavenProjectInfos )
{
this.mavenProjectInfos = mavenProjectInfos;
}
}

View File

@ -0,0 +1,56 @@
package org.jvnet.hudson.maven3.listeners;
/*
* Olivier Lamy
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.Serializable;
import org.apache.maven.project.ProjectBuildingResult;
/**
* @author Olivier Lamy
* @since
*/
public class MavenProjectBuildResult implements Serializable
{
private MavenProjectInfo mavenProjectInfo;
public MavenProjectBuildResult() {
// no op
}
public MavenProjectBuildResult( ProjectBuildingResult projectBuildingResult ) {
// no op
this.mavenProjectInfo = new MavenProjectInfo( projectBuildingResult.getProject() );
}
public MavenProjectInfo getMavenProjectInfo() {
return mavenProjectInfo;
}
public void setMavenProjectInfo( MavenProjectInfo mavenProjectInfo ) {
this.mavenProjectInfo = mavenProjectInfo;
}
@Override
public String toString() {
return mavenProjectInfo == null ? "null mavenProjectInfo" : this.mavenProjectInfo.toString();
}
}

View File

@ -0,0 +1,100 @@
package org.jvnet.hudson.maven3.listeners;
/*
* Olivier Lamy
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.Serializable;
import org.apache.maven.project.MavenProject;
/**
* @author Olivier Lamy
* @since
*/
public class MavenProjectInfo implements Serializable
{
private String displayName;
private String groupId;
private String artifactId;
private String version;
private long buildTime;
public MavenProjectInfo() {
// no-op
}
public MavenProjectInfo(MavenProject mavenProject) {
this.displayName = mavenProject.getName();
this.groupId= mavenProject.getGroupId();
this.artifactId = mavenProject.getArtifactId();
this.version = mavenProject.getVersion();
}
public long getBuildTime() {
return buildTime;
}
public void setBuildTime( long buildTime ) {
this.buildTime = buildTime;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName( String displayName ) {
this.displayName = displayName;
}
public String getGroupId() {
return groupId;
}
public void setGroupId( String groupId ) {
this.groupId = groupId;
}
public String getArtifactId() {
return artifactId;
}
public void setArtifactId( String artifactId ) {
this.artifactId = artifactId;
}
public String getVersion() {
return version;
}
public void setVersion( String version ) {
this.version = version;
}
@Override
public String toString() {
return groupId + ":" + artifactId + ":" + version;
}
}

167
pom.xml
View File

@ -46,6 +46,8 @@ THE SOFTWARE.
<module>ui-samples-plugin</module>
<module>maven-agent</module>
<module>maven-interceptor</module>
<module>maven3-agent</module>
<module>maven3-interceptor</module>
<module>war</module>
<module>test</module>
<module>cli</module>
@ -94,29 +96,50 @@ THE SOFTWARE.
<version>1.39</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.6.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<version>2.6</version>
<configuration>
<systemPropertyVariables>
<java.io.tmpdir>${project.build.directory}</java.io.tmpdir>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
</plugin>
<plugin>
<!--
Both test harness and core uses stapler as an extension,
@ -197,6 +220,7 @@ THE SOFTWARE.
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0</version>
<executions>
@ -257,10 +281,98 @@ THE SOFTWARE.
<optional>true</optional><!-- no need to have this at runtime -->
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${mavenVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>${mavenVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-aether-provider</artifactId>
<version>${mavenVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>${mavenVersion}</version>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-api</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-impl</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-spi</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-util</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-connector-wagon</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-http-lightweight</artifactId>
<version>${wagonVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-file</artifactId>
<version>${wagonVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-provider-api</artifactId>
<version>${wagonVersion}</version>
</dependency>
<dependency>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-inject-plexus</artifactId>
<version>1.4.3.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-classworlds</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<maven.version>2.0.9</maven.version>
<maven.embedder.version>2.0.4</maven.embedder.version>
<mavenVersion>3.0.1</mavenVersion>
<maven.version>${mavenVersion}</maven.version>
<aetherVersion>1.8</aetherVersion>
<wagonVersion>1.0-beta-7</wagonVersion>
<!-- *.html files are in UTF-8, and *.properties are in iso-8859-1, so this configuration is acturally incorrect,
but this suppresses a warning from Maven, and as long as we don't do filtering we should be OK. -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -357,6 +469,37 @@ THE SOFTWARE.
</plugins>
</build>
</profile>
<profile>
<id>m2e</id>
<properties>
<m2BuildDirectory>target</m2BuildDirectory>
</properties>
<activation>
<property>
<name>m2e.version</name>
</property>
</activation>
<build>
<directory>${m2BuildDirectory}</directory>
<plugins>
<plugin>
<groupId>org.maven.ide.eclipse</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>0.12.0</version>
<configuration>
<mappingId>customizable</mappingId>
<configurators>
<configurator id="org.maven.ide.eclipse.jdt.javaConfigurator" />
<configurator id="org.maven.ide.eclipse.plexus.annotations.plexusConfigurator" />
</configurators>
<mojoExecutions>
<mojoExecution>org.apache.maven.plugins:maven-resources-plugin::</mojoExecution>
</mojoExecutions>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories>
@ -370,6 +513,16 @@ THE SOFTWARE.
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>maven.hudson-labs.org</id>
<url>http://maven.hudson-labs.org/content/repositories/releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>

View File

@ -160,10 +160,10 @@ THE SOFTWARE.
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
<scope>test</scope>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>

View File

@ -40,6 +40,7 @@ THE SOFTWARE.
<properties>
<concurrency>1</concurrency> <!-- -1 means # of processors in the system -->
<mavenDebug>false</mavenDebug>
</properties>
<build>
@ -70,6 +71,18 @@ THE SOFTWARE.
<name>hudson.ClassicPluginStrategy.useAntClassLoader</name>
<value>true</value>
</property>
<property>
<name>hudson.maven.debug</name>
<value>${mavenDebug}</value>
</property>
<property>
<name>java.io.tmpdir</name>
<value>${project.build.directory}</value>
</property>
<property>
<name>buildDirectory</name>
<value>${project.build.directory}</value>
</property>
</systemProperties>
</configuration>
</execution>

View File

@ -394,14 +394,31 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
* Returns the older default Maven, while still allowing specification of other bundled Mavens.
*/
protected MavenInstallation configureDefaultMaven() throws Exception {
return configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_20);
return configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_20);
}
protected MavenInstallation configureMaven3() throws Exception {
MavenInstallation mvn = configureDefaultMaven("apache-maven-3.0.1", MavenInstallation.MAVEN_30);
MavenInstallation m3 = new MavenInstallation("apache-maven-3.0.1",mvn.getHome(), NO_PROPERTIES);
hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(m3);
return m3;
}
/**
* Locates Maven2 and configure that as the only Maven in the system.
*/
protected MavenInstallation configureDefaultMaven(String mavenVersion, int mavenReqVersion) throws Exception {
// first if we are running inside Maven, pick that Maven, if it meets the criteria we require..
// does it exists in the buildDirectory see maven-junit-plugin systemProperties
// buildDirectory -> ${project.build.directory} (so no reason to be null ;-) )
String buildDirectory = System.getProperty( "buildDirectory" );
File mavenAlreadyInstalled = new File(buildDirectory, mavenVersion);
if (mavenAlreadyInstalled.exists()) {
MavenInstallation mavenInstallation = new MavenInstallation("default",mavenAlreadyInstalled.getAbsolutePath(), NO_PROPERTIES);
hudson.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(mavenInstallation);
return mavenInstallation;
}
String home = System.getProperty("maven.home");
if(home!=null) {
MavenInstallation mavenInstallation = new MavenInstallation("default",home, NO_PROPERTIES);
@ -417,7 +434,7 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
"To avoid a performance hit, set the system property 'maven.home' to point to a Maven2 installation.");
FilePath mvn = hudson.getRootPath().createTempFile("maven", "zip");
mvn.copyFrom(HudsonTestCase.class.getClassLoader().getResource(mavenVersion + "-bin.zip"));
File mvnHome = createTmpDir();
File mvnHome = new File(buildDirectory);//createTmpDir();
mvn.unzip(new FilePath(mvnHome));
// TODO: switch to tar that preserves file permissions more easily
if(!Functions.isWindows())
@ -1224,9 +1241,7 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
String dependencies = m.getMainAttributes().getValue("Plugin-Dependencies");
if(dependencies!=null) {
MavenEmbedder embedder = new MavenEmbedder(null);
embedder.setClassLoader(getClass().getClassLoader());
embedder.start();
MavenEmbedder embedder = new MavenEmbedder(getClass().getClassLoader(), null);
for( String dep : dependencies.split(",")) {
String[] tokens = dep.split(":");
String artifactId = tokens[0];
@ -1264,7 +1279,6 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
FileUtils.copyFile(dependencyJar, dst);
}
}
embedder.stop();
}
}
}

Binary file not shown.

View File

@ -0,0 +1,82 @@
package hudson.maven;
import hudson.Launcher;
import hudson.maven.reporters.MavenAbstractArtifactRecord;
import hudson.model.BuildListener;
import hudson.tasks.Maven.MavenInstallation;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.jvnet.hudson.test.ExtractResourceSCM;
import org.jvnet.hudson.test.HudsonTestCase;
/**
* @author Olivier Lamy
*/
public class Maven3BuildTest extends HudsonTestCase {
public void testSimpleMaven3Build() throws Exception {
MavenModuleSet m = createMavenProject();
MavenInstallation mavenInstallation = configureMaven3();
m.setMaven( mavenInstallation.getName() );
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceSCM(getClass().getResource("maven3-project.zip")));
m.setGoals( "clean install" );
buildAndAssertSuccess(m);
assertTrue( MavenUtil.maven3orLater( m.getMavenVersionUsed() ) );
}
public void testSimpleMaven3BuildRedeployPublisher() throws Exception {
MavenModuleSet m = createMavenProject();
MavenInstallation mavenInstallation = configureMaven3();
m.setMaven( mavenInstallation.getName() );
File repo = createTmpDir();
FileUtils.cleanDirectory( repo );
m.getReporters().add(new TestReporter());
m.getPublishersList().add(new RedeployPublisher("",repo.toURI().toString(),true, false));
m.setScm(new ExtractResourceSCM(getClass().getResource("maven3-project.zip")));
m.setGoals( "clean install" );
buildAndAssertSuccess(m);
assertTrue( MavenUtil.maven3orLater( m.getMavenVersionUsed() ) );
File artifactDir = new File(repo,"com/mycompany/app/my-app/1.7-SNAPSHOT/");
String[] files = artifactDir.list( new FilenameFilter()
{
public boolean accept( File dir, String name )
{
System.out.println("file name : " +name );
return name.endsWith( ".jar" );
}
});
assertTrue("SNAPSHOT exist",!files[0].contains( "SNAPSHOT" ));
assertTrue("file not ended with -1.jar", files[0].endsWith( "-1.jar" ));
}
public void testSiteBuildWithForkedMojo() throws Exception {
MavenModuleSet m = createMavenProject();
MavenInstallation mavenInstallation = configureMaven3();
m.setMaven( mavenInstallation.getName() );
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceSCM(getClass().getResource("maven3-project.zip")));
m.setGoals( "clean site" );
buildAndAssertSuccess(m);
assertTrue( MavenUtil.maven3orLater( m.getMavenVersionUsed() ) );
}
private static class TestReporter extends MavenReporter {
@Override
public boolean end(MavenBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
assertNotNull(build.getProject().getWorkspace());
assertNotNull(build.getWorkspace());
return true;
}
}
}

View File

@ -34,32 +34,32 @@ public class MavenMultiModuleTest extends HudsonTestCase {
configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject();
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod.zip"),
getClass().getResource("maven-multimod-changes.zip")));
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod.zip"),
getClass().getResource("maven-multimod-changes.zip")));
buildAndAssertSuccess(m);
// Now run a second build with the changes.
m.setIncrementalBuild(true);
buildAndAssertSuccess(m);
MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
buildAndAssertSuccess(m);
// Now run a second build with the changes.
m.setIncrementalBuild(true);
buildAndAssertSuccess(m);
MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
}
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
}
long summedModuleDuration = 0;
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
@ -75,39 +75,39 @@ public class MavenMultiModuleTest extends HudsonTestCase {
MavenModuleSet m = createMavenProject();
m.setRootPOM("parent/pom.xml");
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod-rel-base.zip"),
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod-rel-base.zip"),
getClass().getResource("maven-multimod-changes.zip")));
buildAndAssertSuccess(m);
// Now run a second build with the changes.
m.setIncrementalBuild(true);
buildAndAssertSuccess(m);
MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
// Now run a second build with the changes.
m.setIncrementalBuild(true);
buildAndAssertSuccess(m);
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
}
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
}
long summedModuleDuration = 0;
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
summedModuleDuration += modBuild.getDuration();
}
assertTrue("duration of moduleset build should be greater-equal than sum of the module builds",
pBuild.getDuration() >= summedModuleDuration);
pBuild.getDuration() >= summedModuleDuration);
}
@Bug(7684)
@ -116,34 +116,34 @@ public class MavenMultiModuleTest extends HudsonTestCase {
MavenModuleSet m = createMavenProject();
m.setRootPOM("../parent/pom.xml");
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod-rel-base.zip"),
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod-rel-base.zip"),
getClass().getResource("maven-multimod-changes.zip"),
"moduleA"));
buildAndAssertSuccess(m);
// Now run a second build with the changes.
m.setIncrementalBuild(true);
buildAndAssertSuccess(m);
// Now run a second build with the changes.
m.setIncrementalBuild(true);
buildAndAssertSuccess(m);
MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
}
MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
}
long summedModuleDuration = 0;
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
summedModuleDuration += modBuild.getDuration();
@ -202,30 +202,30 @@ public class MavenMultiModuleTest extends HudsonTestCase {
public void testMultiModMavenNonRecursiveParsing() throws Exception {
configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject();
m.setGoals("clean install -N");
m.setGoals("clean install -N");
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceSCM(getClass().getResource("maven-multimod.zip")));
m.setScm(new ExtractResourceSCM(getClass().getResource("maven-multimod.zip")));
buildAndAssertSuccess(m);
buildAndAssertSuccess(m);
MavenModuleSetBuild pBuild = m.getLastBuild();
MavenModuleSetBuild pBuild = m.getLastBuild();
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:multimod-top")) {
assertEquals("moduleA should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:multimod-top")) {
assertEquals("moduleA should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
}
}
}
@ -238,36 +238,36 @@ public class MavenMultiModuleTest extends HudsonTestCase {
configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject();
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod-incr.zip"),
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod-incr.zip"),
getClass().getResource("maven-multimod-changes.zip")));
assertBuildStatus(Result.UNSTABLE, m.scheduleBuild2(0).get());
// Now run a second build with the changes.
m.setIncrementalBuild(true);
assertBuildStatus(Result.UNSTABLE, m.scheduleBuild2(0).get());
MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
// Now run a second build with the changes.
m.setIncrementalBuild(true);
assertBuildStatus(Result.UNSTABLE, m.scheduleBuild2(0).get());
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
assertEquals("Parent build should have Result.UNSTABLE", Result.UNSTABLE, pBuild.getResult());
MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
assertEquals("Parent build should have Result.UNSTABLE", Result.UNSTABLE, pBuild.getResult());
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleA")) {
assertEquals("moduleA should have Result.UNSTABLE", Result.UNSTABLE, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleD")) {
assertEquals("moduleD should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
}
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleA")) {
assertEquals("moduleA should have Result.UNSTABLE", Result.UNSTABLE, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleD")) {
assertEquals("moduleD should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
}
}
}
/**
@ -278,29 +278,29 @@ public class MavenMultiModuleTest extends HudsonTestCase {
configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject();
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceSCM(getClass().getResource("maven-multimod-incr.zip")));
m.setScm(new ExtractResourceSCM(getClass().getResource("maven-multimod-incr.zip")));
assertBuildStatus(Result.UNSTABLE, m.scheduleBuild2(0).get());
assertBuildStatus(Result.UNSTABLE, m.scheduleBuild2(0).get());
MavenModuleSetBuild pBuild = m.getLastBuild();
MavenModuleSetBuild pBuild = m.getLastBuild();
assertEquals("Parent build should have Result.UNSTABLE", Result.UNSTABLE, pBuild.getResult());
assertEquals("Parent build should have Result.UNSTABLE", Result.UNSTABLE, pBuild.getResult());
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleA")) {
assertEquals("moduleA should have Result.UNSTABLE", Result.UNSTABLE, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleD")) {
assertEquals("moduleD should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
}
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleA")) {
assertEquals("moduleA should have Result.UNSTABLE", Result.UNSTABLE, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleD")) {
assertEquals("moduleD should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
}
}
}
/*

View File

@ -24,6 +24,9 @@
package hudson.maven;
import hudson.model.Result;
import hudson.tasks.Maven.MavenInstallation;
import org.apache.commons.io.FileUtils;
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.ExtractResourceSCM;
import org.jvnet.hudson.test.HudsonTestCase;
@ -31,6 +34,7 @@ import org.jvnet.hudson.test.SingleFileSCM;
import org.jvnet.hudson.test.Email;
import java.io.File;
import java.io.FilenameFilter;
/**
* @author Kohsuke Kawaguchi
@ -98,13 +102,95 @@ public class RedeployPublisherTest extends HudsonTestCase {
assertTrue("tar.gz doesn't exist",new File(repo,"test/test/0.1-SNAPSHOT/test-0.1-SNAPSHOT-bin.tar.gz").exists());
}
public void testTarGzUniqueVersionTrue() throws Exception {
configureDefaultMaven();
MavenModuleSet m2 = createMavenProject();
File repo = createTmpDir();
FileUtils.cleanDirectory( repo );
// a fake build
m2.setScm(new SingleFileSCM("pom.xml",getClass().getResource("targz-artifact.pom")));
m2.getPublishersList().add(new RedeployPublisher("",repo.toURI().toString(),true, false));
MavenModuleSetBuild b = m2.scheduleBuild2(0).get();
assertBuildStatus(Result.SUCCESS, b);
File artifactDir = new File(repo,"test/test/0.1-SNAPSHOT/");
String[] files = artifactDir.list( new FilenameFilter()
{
public boolean accept( File dir, String name )
{
return name.endsWith( "tar.gz" );
}
});
assertFalse("tar.gz doesn't exist",new File(repo,"test/test/0.1-SNAPSHOT/test-0.1-SNAPSHOT-bin.tar.gz").exists());
assertTrue("tar.gz doesn't exist",!files[0].contains( "SNAPSHOT" ));
}
public void testTarGzMaven3() throws Exception {
MavenModuleSet m3 = createMavenProject();
MavenInstallation mvn = configureMaven3();
m3.setMaven( mvn.getName() );
File repo = createTmpDir();
FileUtils.cleanDirectory( repo );
// a fake build
m3.setScm(new SingleFileSCM("pom.xml",getClass().getResource("targz-artifact.pom")));
m3.getPublishersList().add(new RedeployPublisher("",repo.toURI().toString(),false, false));
MavenModuleSetBuild b = m3.scheduleBuild2(0).get();
assertBuildStatus(Result.SUCCESS, b);
assertTrue( MavenUtil.maven3orLater( m3.getMavenVersionUsed() ) );
File artifactDir = new File(repo,"test/test/0.1-SNAPSHOT/");
String[] files = artifactDir.list( new FilenameFilter()
{
public boolean accept( File dir, String name )
{
return name.endsWith( "tar.gz" );
}
});
assertFalse("tar.gz doesn't exist",new File(repo,"test/test/0.1-SNAPSHOT/test-0.1-SNAPSHOT-bin.tar.gz").exists());
assertTrue("tar.gz doesn't exist",!files[0].contains( "SNAPSHOT" ));
}
public void testTarGzUniqueVersionTrueMaven3() throws Exception {
MavenModuleSet m3 = createMavenProject();
MavenInstallation mvn = configureMaven3();
m3.setMaven( mvn.getName() );
File repo = createTmpDir();
FileUtils.cleanDirectory( repo );
// a fake build
m3.setScm(new SingleFileSCM("pom.xml",getClass().getResource("targz-artifact.pom")));
m3.getPublishersList().add(new RedeployPublisher("",repo.toURI().toString(),true, false));
MavenModuleSetBuild b = m3.scheduleBuild2(0).get();
assertBuildStatus(Result.SUCCESS, b);
assertTrue( MavenUtil.maven3orLater( m3.getMavenVersionUsed() ) );
File artifactDir = new File(repo,"test/test/0.1-SNAPSHOT/");
String[] files = artifactDir.list( new FilenameFilter()
{
public boolean accept( File dir, String name )
{
return name.endsWith( "tar.gz" );
}
});
assertFalse("tar.gz doesn't exist",new File(repo,"test/test/0.1-SNAPSHOT/test-0.1-SNAPSHOT-bin.tar.gz").exists());
assertTrue("tar.gz doesn't exist",!files[0].contains( "SNAPSHOT" ));
}
@Bug(3773)
public void testDeployUnstable() throws Exception {
configureDefaultMaven();
MavenModuleSet m2 = createMavenProject();
File repo = createTmpDir();
FileUtils.cleanDirectory( repo );
// a build with a failing unit tests
m2.setScm(new ExtractResourceSCM(getClass().getResource("maven-test-failure-findbugs.zip")));
m2.getPublishersList().add(new RedeployPublisher("",repo.toURI().toString(),false, true));

View File

@ -1,2 +0,0 @@
[InternetShortcut]
URL=http://creativecommons.org/licenses/by-sa/2.5/

View File

@ -120,7 +120,7 @@ THE SOFTWARE.
<resolveArtifact artifactId="remoting" tofile="${basedir}/target/generated-resources/WEB-INF/slave.jar" />
<resolveArtifact groupId="${project.groupId}" artifactId="cli" classifier="jar-with-dependencies" version="${project.version}" type="jar" tofile="${basedir}/target/generated-resources/WEB-INF/hudson-cli.jar" />
<resolveArtifact groupId="org.jvnet.hudson.winstone" artifactId="winstone" version="0.9.10-hudson-24" type="jar" tofile="${basedir}/target/generated-resources/winstone.jar" />
<!-- bundled plugins -->
<resolveArtifact type="hpi" groupId="${project.groupId}" artifactId="maven-plugin" version="${project.version}" tofile="${basedir}/target/generated-resources/WEB-INF/plugins/maven-plugin.hpi" />
<resolveArtifact type="hpi" groupId="org.jvnet.hudson.plugins" artifactId="ssh-slaves" version="0.14" tofile="${basedir}/target/generated-resources/WEB-INF/plugins/ssh-slaves.hpi" />
@ -237,6 +237,26 @@ THE SOFTWARE.
</exclusion>
</exclusions>
</dependency>
<!-- declare this in reactors, so i can use now directly : mvn install -pl war -am to get the war -->
<!-- TO REMOVE when maven-plugin won't be anymore a bundle plugin -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>maven-plugin</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>remoting</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>cli</artifactId>
<classifier>jar-with-dependencies</classifier>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<!-- offline profiler API when we need it -->
<!--dependency>
<groupId>com.yourkit.api</groupId>