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 *.iws
*.ipr *.ipr
.idea .idea
=======
# eclipse project file # eclipse project file
.settings .settings
.classpath .classpath
.project .project
build
war/images/16x16 war/images/16x16
war/images/24x24 war/images/24x24
@ -29,3 +31,5 @@ debian/configure-stamp
*.debhelper.log *.debhelper.log
hudson_*.build hudson_*.build
hudson_*.changes hudson_*.changes
=======
push-build.sh

View File

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

View File

@ -646,6 +646,13 @@ public abstract class PluginManager extends AbstractModelObject {
} }
return Collections.enumeration(resources); 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()); 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_20 = 0;
public static final int MAVEN_21 = 1; 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. * Represents the minimum required Maven version - constants defined above.
*/ */
public boolean meetsMavenReqVersion(Launcher launcher, int mavenReqVersion) throws IOException, InterruptedException { 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>() { String mavenVersion = launcher.getChannel().call(new Callable<String,IOException>() {
public String call() throws IOException { public String call() throws IOException {
File[] jars = new File(getHomeDir(),"lib").listFiles(); 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")) if(mavenVersion.startsWith("maven-2.") && !mavenVersion.startsWith("maven-2.0"))
return true; return true;
} }
else if (mavenReqVersion == MAVEN_30) {
if(mavenVersion.startsWith("maven-3.") && !mavenVersion.startsWith("maven-2.0"))
return true;
}
} }
return false; return false;

View File

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

View File

@ -23,25 +23,25 @@
*/ */
package hudson.maven.agent; package hudson.maven.agent;
import org.codehaus.classworlds.ClassRealm; import java.io.BufferedInputStream;
import org.codehaus.classworlds.ClassWorld; import java.io.BufferedOutputStream;
import org.codehaus.classworlds.DefaultClassRealm;
import org.codehaus.classworlds.Launcher;
import org.codehaus.classworlds.NoSuchRealmException;
import java.io.File; import java.io.File;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.net.Socket; import java.net.Socket;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; 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, * Entry point for launching Maven and Hudson remoting in the same VM,
* in the classloader layout that Maven expects. * 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 // 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. // create a realm for loading remoting subsystem.
// this needs to be able to see maven. // 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()); ClassRealm remoting = new DefaultClassRealm(launcher.getWorld(),"hudson-remoting", launcher.getSystemClassLoader());
remoting.setParent(launcher.getWorld().getRealm("plexus.core.maven")); remoting.setParent(launcher.getWorld().getRealm("plexus.core.maven"));
remoting.addConstituent(remotingJar.toURI().toURL()); remoting.addConstituent(remotingJar.toURI().toURL());
@ -156,8 +161,11 @@ public class Main {
/** /**
* Called by the code in remoting to launch. * 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 { public static int launch(String[] args) throws NoSuchMethodException, IllegalAccessException, NoSuchRealmException, InvocationTargetException, ClassNotFoundException {
//ClassWorld world = ClassWorldAdapter.getInstance( launcher.getWorld() );
ClassWorld world = launcher.getWorld(); ClassWorld world = launcher.getWorld();
Set builtinRealms = new HashSet(world.getRealms()); Set builtinRealms = new HashSet(world.getRealms());

View File

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

View File

@ -23,16 +23,19 @@
*/ */
package hudson.maven.agent; 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.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.DefaultPluginManager; import org.apache.maven.plugin.DefaultPluginManager;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.PluginConfigurationException; import org.apache.maven.plugin.PluginConfigurationException;
import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.InvalidDependencyVersionException; import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.reporting.MavenReport; 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.ComponentConfigurator;
import org.codehaus.plexus.component.configurator.ConfigurationListener; import org.codehaus.plexus.component.configurator.ConfigurationListener;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; 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.ComponentLifecycleException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.configuration.PlexusConfiguration; 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 * Description in META-INF/plexus/components.xml makes it possible to use this instead of the default
* plugin manager. * 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> 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> <url>http://wiki.hudson-ci.org/display/HUDSON/Maven+2+Project+Plugin</url>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.jvnet.hudson.main</groupId> <groupId>org.jvnet.hudson.main</groupId>
<artifactId>hudson-core</artifactId> <artifactId>hudson-core</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId> <artifactId>servlet-api</artifactId>
<version>2.4</version> <version>2.4</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>maven-agent</artifactId> <artifactId>maven-agent</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> <exclusions>
<dependency> <exclusion>
<groupId>org.jvnet.hudson</groupId> <groupId>classworlds</groupId>
<artifactId>maven2.1-interceptor</artifactId> <artifactId>classworlds</artifactId>
<version>1.2</version> </exclusion>
</dependency> </exclusions>
<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> <dependency>
<!-- commonly used wagon provider --> <groupId>org.jvnet.hudson.main</groupId>
<groupId>org.jvnet.hudson</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>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> <artifactId>wagon-webdav</artifactId>
<version>1.0-beta-2-hudson-1</version> </exclusion>
<exclusions>
<exclusion>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build> <!-- prefer net.sourceforge.nekohtml:nekohtml:jar:1.9.13 so that we use consistent version across Hudson -->
<!-- <exclusion>
Since new versions need to overwrite old versions, it's better <groupId>nekohtml</groupId>
not to have version number in the .hpi file name. <artifactId>nekohtml</artifactId>
--> </exclusion>
<finalName>${project.artifactId}</finalName> <exclusion>
<defaultGoal>package</defaultGoal> <groupId>nekohtml</groupId>
<plugins> <artifactId>xercesMinimal</artifactId>
<plugin> </exclusion>
<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> </exclusions>
<id>cobertura2</id> </dependency>
<build>
<plugins> <dependency>
<plugin> <!-- commonly used wagon provider -->
<groupId>org.codehaus.mojo</groupId> <groupId>org.jvnet.hudson</groupId>
<artifactId>cobertura-maven-plugin</artifactId> <artifactId>wagon-webdav</artifactId>
<version>2.4-apb-SNAPSHOT</version> <version>1.0-beta-2-hudson-1</version>
<inherited>true</inherited> <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> <configuration>
<formats> <fileMask>Messages.properties</fileMask>
<format>html</format> <outputDirectory>target/generated-sources/localizer</outputDirectory>
<format>xml</format>
</formats>
</configuration> </configuration>
<executions> </execution>
<execution> </executions>
<id>coverage-instrument</id> </plugin>
<phase>process-test-classes</phase> <plugin>
<goals> <groupId>org.jvnet.maven-antrun-extended-plugin</groupId>
<goal>instrument</goal> <artifactId>maven-antrun-extended-plugin</artifactId>
</goals> <executions>
</execution> <execution>
<execution> <id>resgen</id>
<id>coverage-report</id> <phase>generate-resources</phase>
<phase>test</phase> <goals>
<goals> <goal>run</goal>
<goal>generate-report</goal> </goals>
</goals> <configuration>
</execution> <verifyArtifact>false</verifyArtifact>
</executions> <tasks>
</plugin> <mkdir dir="target/classes" />
</plugins>
</build> <!-- classworld 1.1 for maven 2 builds -->
</profile> <resolveArtifact groupId="classworlds" artifactId="classworlds" version="1.1" type="jar" tofile="target/classes/classworlds.jar" />
</profiles> </tasks>
</project> </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; package hudson.maven;
import hudson.model.TaskListener; import hudson.model.TaskListener;
import org.apache.maven.embedder.AbstractMavenEmbedderLogger;
import org.apache.maven.embedder.MavenEmbedderLogger;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.StringTokenizer; 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 * {@link MavenEmbedderLogger} implementation that
* sends output to {@link TaskListener}. * sends output to {@link TaskListener}.
* *
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
*/ */
public final class EmbedderLoggerImpl extends AbstractMavenEmbedderLogger { public final class EmbedderLoggerImpl extends MavenLoggerManager {
private final PrintStream logger; private final PrintStream logger;
public EmbedderLoggerImpl(TaskListener listener) { public EmbedderLoggerImpl(TaskListener listener, int threshold) {
super(new ConsoleLogger( threshold, "hudson-logger" ));
logger = listener.getLogger(); logger = listener.getLogger();
} }
@ -57,22 +60,22 @@ public final class EmbedderLoggerImpl extends AbstractMavenEmbedderLogger {
} }
public void debug(String message, Throwable throwable) { 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) { 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) { 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) { 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) { 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; package hudson.maven;
import static hudson.Util.intern;
import hudson.Util; import hudson.Util;
import hudson.model.Hudson; import hudson.model.Hudson;
import hudson.remoting.Which; import hudson.remoting.Which;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import hudson.util.ReflectionUtils;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.kohsuke.stapler.Stapler;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.Map; import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.logging.Logger; import java.util.Map;
import java.util.logging.Level; 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. * Persisted record of mojo execution.
@ -80,7 +82,7 @@ public final class ExecutedMojo implements Serializable {
*/ */
public final String digest; 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.groupId = mojo.pluginName.groupId;
this.artifactId = mojo.pluginName.artifactId; this.artifactId = mojo.pluginName.artifactId;
this.version = mojo.pluginName.version; this.version = mojo.pluginName.version;
@ -92,7 +94,7 @@ public final class ExecutedMojo implements Serializable {
MojoDescriptor md = mojo.mojoExecution.getMojoDescriptor(); MojoDescriptor md = mojo.mojoExecution.getMojoDescriptor();
PluginDescriptor pd = md.getPluginDescriptor(); PluginDescriptor pd = md.getPluginDescriptor();
try { 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))); digest = Util.getDigestOf(new FileInputStream(Which.jarFile(clazz)));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
LOGGER.log(Level.WARNING, "Failed to locate jar for "+md.getImplementation(),e); LOGGER.log(Level.WARNING, "Failed to locate jar for "+md.getImplementation(),e);
@ -102,6 +104,28 @@ public final class ExecutedMojo implements Serializable {
this.digest = digest; 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. * 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.slaves.WorkspaceList.Lease;
import hudson.maven.agent.AbortException; import hudson.maven.agent.AbortException;
import hudson.model.BuildListener; import hudson.model.BuildListener;
import hudson.model.Computer;
import hudson.model.Result; import hudson.model.Result;
import hudson.model.Run; import hudson.model.Run;
import hudson.model.Environment; import hudson.model.Environment;
@ -40,8 +41,10 @@ import hudson.remoting.Channel;
import hudson.scm.ChangeLogSet; import hudson.scm.ChangeLogSet;
import hudson.scm.ChangeLogSet.Entry; import hudson.scm.ChangeLogSet.Entry;
import hudson.tasks.BuildWrapper; import hudson.tasks.BuildWrapper;
import hudson.tasks.Maven.MavenInstallation;
import hudson.util.ArgumentListBuilder; import hudson.util.ArgumentListBuilder;
import org.apache.maven.BuildFailureException; import org.apache.maven.BuildFailureException;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager; import org.apache.maven.execution.ReactorManager;
import org.apache.maven.lifecycle.LifecycleExecutionException; 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; private final SplittableBuildListener listener;
long startTime; long startTime;
private final OutputStream log; 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 EnvVars envVars = getEnvironment(listener); // buildEnvironments should be set up first
ProcessCache.MavenProcess process = mavenProcessCache.get(launcher.getChannel(), listener, MavenInstallation mvn = getProject().getParent().getMaven();
new MavenProcessFactory(getParent().getParent(),launcher,envVars,null));
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"); ArgumentListBuilder margs = new ArgumentListBuilder("-N","-B");
if(mms.usesPrivateRepository()) if(mms.usesPrivateRepository())
@ -538,25 +568,33 @@ public class MavenBuild extends AbstractMavenBuild<MavenModule,MavenBuild> {
systemProps.put("hudson.build.number",String.valueOf(getNumber())); systemProps.put("hudson.build.number",String.valueOf(getNumber()));
boolean normalExit = false; boolean normalExit = false;
try { if (maven3orLater)
Result r = process.call(new Builder( {
listener,new ProxyImpl(), // FIXME here for maven 3 builds
reporters.toArray(new MavenReporter[reporters.size()]), margs.toList(), systemProps)); return Result.ABORTED;
normalExit = true; }
return r; else
} finally { {
if(normalExit) process.recycle(); try {
else process.discard(); 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 // tear down in reverse order
boolean failed=false; boolean failed=false;
for( int i=buildEnvironments.size()-1; i>=0; i-- ) { for( int i=buildEnvironments.size()-1; i>=0; i-- ) {
if (!buildEnvironments.get(i).tearDown(MavenBuild.this,listener)) { if (!buildEnvironments.get(i).tearDown(MavenBuild.this,listener)) {
failed=true; 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 * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * 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.AbortException;
import hudson.maven.agent.Main; import hudson.maven.agent.Main;
import hudson.maven.agent.PluginManagerInterceptor;
import hudson.maven.agent.PluginManagerListener; import hudson.maven.agent.PluginManagerListener;
import hudson.maven.reporters.SurefireArchiver; import hudson.maven.reporters.SurefireArchiver;
import hudson.model.BuildListener; import hudson.model.BuildListener;
import hudson.model.Hudson;
import hudson.model.Result; import hudson.model.Result;
import hudson.remoting.Callable; import hudson.remoting.Callable;
import hudson.remoting.Channel; import hudson.remoting.Channel;
@ -40,6 +39,7 @@ import hudson.util.IOException2;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -50,7 +50,6 @@ import org.apache.maven.BuildFailureException;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager; import org.apache.maven.execution.ReactorManager;
import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.lifecycle.LifecycleExecutorInterceptor;
import org.apache.maven.lifecycle.LifecycleExecutorListener; import org.apache.maven.lifecycle.LifecycleExecutorListener;
import org.apache.maven.monitor.event.EventDispatcher; import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.plugin.Mojo; import org.apache.maven.plugin.Mojo;
@ -74,20 +73,8 @@ import org.codehaus.plexus.configuration.PlexusConfiguration;
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
* @since 1.133 * @since 1.133
*/ */
public abstract class MavenBuilder implements DelegatingCallable<Result,IOException> { public abstract class MavenBuilder extends AbstractMavenBuilder 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;
/** /**
* Flag needs to be set at the constructor, so that this reflects * 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 transient /*final*/ List<Future<?>> futures;
protected MavenBuilder(BuildListener listener, List<String> goals, Map<String, String> systemProps) { protected MavenBuilder(BuildListener listener, List<String> goals, Map<String, String> systemProps) {
this.listener = listener; super( listener, goals, systemProps );
this.goals = goals;
this.systemProps = systemProps;
} }
/** /**
@ -142,15 +127,29 @@ public abstract class MavenBuilder implements DelegatingCallable<Result,IOExcept
*/ */
abstract void onReportGenerated(MavenProject project, MavenReportInfo report) throws IOException, InterruptedException, AbortException; 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. * This code is executed inside the maven jail process.
*/ */
public Result call() throws IOException { 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 { try {
futures = new ArrayList<Future<?>>(); futures = new ArrayList<Future<?>>();
Adapter a = new Adapter(this); Adapter a = new Adapter(this);
callSetListenerWithReflectOnInterceptors( a, mavenJailProcessClassLoader );
/*
PluginManagerInterceptor.setListener(a); PluginManagerInterceptor.setListener(a);
LifecycleExecutorInterceptor.setListener(a); LifecycleExecutorInterceptor.setListener(a);
*/
markAsSuccess = false; markAsSuccess = false;
@ -202,46 +201,83 @@ public abstract class MavenBuilder implements DelegatingCallable<Result,IOExcept
listener.getLogger().println(Messages.MavenBuilder_Failed()); listener.getLogger().println(Messages.MavenBuilder_Failed());
return Result.SUCCESS; return Result.SUCCESS;
} }
return Result.FAILURE; return Result.FAILURE;
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
throw new IOException2(e); throw new IOException2(e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new IOException2(e); throw new IOException2(e);
} catch (NoSuchRealmException e) { } catch (RuntimeException e) {
throw new IOException2(e); throw new IOException2(e);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
throw new IOException2(e); throw new IOException2(e);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new IOException2(e); throw new IOException2(e);
}
catch ( NoSuchRealmException e ) {
throw new IOException2(e);
} finally { } finally {
PluginManagerInterceptor.setListener(null); //PluginManagerInterceptor.setListener(null);
LifecycleExecutorInterceptor.setListener(null); //LifecycleExecutorInterceptor.setListener(null);
callSetListenerWithReflectOnInterceptorsQuietly( null, mavenJailProcessClassLoader );
} }
} }
private String formatArgs(List<String> args) { private void callSetListenerWithReflectOnInterceptors( PluginManagerListener pluginManagerListener, ClassLoader cl )
StringBuilder buf = new StringBuilder("Executing Maven: "); throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException,
for (String arg : args) { IllegalAccessException, InvocationTargetException
final String argPassword = "-Dpassword=" ; {
String filteredArg = arg ; if (pluginManagerInterceptorClazz == null)
// check if current arg is password arg. Then replace password by ***** {
if (arg.startsWith(argPassword)) { pluginManagerInterceptorClazz = cl.loadClass( "hudson.maven.agent.PluginManagerInterceptor" );
filteredArg=argPassword+"*********";
}
buf.append(' ').append(filteredArg);
} }
return buf.toString(); Method setListenerMethod =
pluginManagerInterceptorClazz.getMethod( "setListener",
new Class[] { cl.loadClass( "hudson.maven.agent.PluginManagerListener" ) } );
setListenerMethod.invoke( null, new Object[] { pluginManagerListener } );
if (lifecycleInterceptorClazz == null)
{
lifecycleInterceptorClazz = cl.loadClass( "org.apache.maven.lifecycle.LifecycleExecutorInterceptor" );
}
setListenerMethod =
lifecycleInterceptorClazz.getMethod( "setListener",
new Class[] { cl.loadClass( "org.apache.maven.lifecycle.LifecycleExecutorListener" ) } );
setListenerMethod.invoke( null, new Object[] { pluginManagerListener } );
} }
private String format(NumberFormat n, long nanoTime) { private void callSetListenerWithReflectOnInterceptorsQuietly( PluginManagerListener pluginManagerListener, ClassLoader cl )
return n.format(nanoTime/1000000); {
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 );
}
} }
// since reporters might be from plugins, use the uberjar to resolve them.
public ClassLoader getClassLoader() {
return Hudson.getInstance().getPluginManager().uberClassLoader;
}
/** /**
* Receives {@link PluginManagerListener} and {@link LifecycleExecutorListener} events * Receives {@link PluginManagerListener} and {@link LifecycleExecutorListener} events

View File

@ -25,10 +25,11 @@ package hudson.maven;
import hudson.Extension; import hudson.Extension;
import hudson.FilePath; import hudson.FilePath;
import hudson.maven.agent.AbortException;
import hudson.maven.agent.Main; import hudson.maven.agent.Main;
import hudson.maven.agent.PluginManagerInterceptor;
import hudson.maven.agent.Maven21Interceptor; import hudson.maven.agent.Maven21Interceptor;
import hudson.model.Computer; import hudson.model.Computer;
import hudson.model.Hudson;
import hudson.model.TaskListener; import hudson.model.TaskListener;
import hudson.remoting.Channel; import hudson.remoting.Channel;
import hudson.remoting.Which; import hudson.remoting.Which;
@ -38,8 +39,11 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.Project; 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> * 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 { public void preOnline(Computer c, Channel channel,FilePath root, TaskListener listener) throws IOException, InterruptedException {
PrintStream logger = listener.getLogger(); PrintStream logger = listener.getLogger();
copyJar(logger, root, Main.class, "maven-agent"); 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, 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; package hudson.maven;
import hudson.*; import static hudson.Util.fixEmpty;
import hudson.model.*; 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.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;
import hudson.model.Queue.Task; 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.CollectionSearchIndex;
import hudson.search.SearchIndexBuilder; 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.Maven.MavenInstallation;
import hudson.tasks.Publisher;
import hudson.tasks.junit.JUnitResultArchiver; import hudson.tasks.junit.JUnitResultArchiver;
import hudson.util.CopyOnWriteMap; import hudson.util.CopyOnWriteMap;
import hudson.util.DescribableList; import hudson.util.DescribableList;
import hudson.util.FormValidation; import hudson.util.FormValidation;
import hudson.util.Function1; 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 net.sf.json.JSONObject;
import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported; 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. * Group of {@link MavenModule}s.
* *
@ -145,6 +181,8 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
*/ */
private boolean archivingDisabled = false; private boolean archivingDisabled = false;
private String mavenVersionUsed;
/** /**
* Reporters configured at {@link MavenModuleSet} level. Applies to all {@link MavenModule} builds. * Reporters configured at {@link MavenModuleSet} level. Applies to all {@link MavenModule} builds.
*/ */
@ -599,6 +637,15 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
save(); 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, * If the list of configured goals contain the "-P" option,
* return the configured profiles. Otherwise null. * return the configured profiles. Otherwise null.
@ -837,4 +884,6 @@ public final class MavenModuleSet extends AbstractMavenProject<MavenModuleSet,Ma
JUnitResultArchiver.class // done by SurefireArchiver JUnitResultArchiver.class // done by SurefireArchiver
)); ));
} }
} }

View File

@ -2,7 +2,7 @@
* The MIT License * The MIT License
* *
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -24,13 +24,29 @@
*/ */
package hudson.maven; 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.FilePath.FileCallable;
import hudson.Launcher;
import hudson.Util;
import hudson.maven.MavenBuild.ProxyImpl2; import hudson.maven.MavenBuild.ProxyImpl2;
import hudson.maven.reporters.MavenFingerprinter; import hudson.maven.reporters.MavenFingerprinter;
import hudson.maven.reporters.MavenMailer; 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.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.Channel;
import hudson.remoting.VirtualChannel; import hudson.remoting.VirtualChannel;
import hudson.scm.ChangeLogSet; import hudson.scm.ChangeLogSet;
@ -39,9 +55,33 @@ import hudson.tasks.MailSender;
import hudson.tasks.Maven.MavenInstallation; import hudson.tasks.Maven.MavenInstallation;
import hudson.util.ArgumentListBuilder; import hudson.util.ArgumentListBuilder;
import hudson.util.IOUtils; import hudson.util.IOUtils;
import hudson.util.MaskingClassLoader;
import hudson.util.StreamTaskListener; 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.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.MavenSession;
import org.apache.maven.execution.ReactorManager; import org.apache.maven.execution.ReactorManager;
import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.lifecycle.LifecycleExecutionException;
@ -50,15 +90,9 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException; import org.apache.maven.project.ProjectBuildingException;
import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.StaplerResponse;
import org.apache.commons.io.FilenameUtils; import org.sonatype.aether.transfer.TransferCancelledException;
import org.sonatype.aether.transfer.TransferEvent;
import java.io.*; import org.sonatype.aether.transfer.TransferListener;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import static hudson.model.Result.FAILURE;
/** /**
* {@link Build} for {@link MavenModuleSet}. * {@link Build} for {@link MavenModuleSet}.
@ -427,6 +461,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
PrintStream logger = listener.getLogger(); PrintStream logger = listener.getLogger();
Result r = null; Result r = null;
try { try {
EnvVars envVars = getEnvironment(listener); EnvVars envVars = getEnvironment(listener);
MavenInstallation mvn = project.getMaven(); MavenInstallation mvn = project.getMaven();
if(mvn==null) if(mvn==null)
@ -435,6 +470,14 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
mvn = mvn.forEnvironment(envVars).forNode(Computer.currentComputer().getNode(), listener); 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()) { if(!project.isAggregatorStyleBuild()) {
parsePoms(listener, logger, envVars, mvn); parsePoms(listener, logger, envVars, mvn);
// start module builds // 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. // we act as if incrementalBuild is not set if there are no changes.
if (!MavenModuleSetBuild.this.getChangeSet().isEmptySet() if (!MavenModuleSetBuild.this.getChangeSet().isEmptySet()
&& project.isIncrementalBuild()) { && project.isIncrementalBuild()) {
// If there are changes for this module, add it. //If there are changes for this module, add it.
// Also add it if we've never seen this module before, // Also add it if we've never seen this module before,
// or if the previous build of this module failed or was unstable. // or if the previous build of this module failed or was unstable.
if ((mb.getPreviousBuiltBuild() == null) || if ((mb.getPreviousBuiltBuild() == null) ||
(!getChangeSetFor(m).isEmpty()) (!getChangeSetFor(m).isEmpty())
|| (mb.getPreviousBuiltBuild().getResult().isWorseThan(Result.SUCCESS))) { || (mb.getPreviousBuiltBuild().getResult().isWorseThan(Result.SUCCESS))) {
@ -499,16 +542,34 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
if(!pom.exists() && parentLoc.exists()) if(!pom.exists() && parentLoc.exists())
pom = parentLoc; 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()); ArgumentListBuilder margs = new ArgumentListBuilder().add("-B").add("-f", pom.getRemote());
if(project.usesPrivateRepository()) if(project.usesPrivateRepository())
margs.add("-Dmaven.repo.local="+getWorkspace().child(".repository")); 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 // 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, // listed in changedModules, do the Maven incremental build commands - if there are no changed modules,
// We're building everything anyway. // 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("-amd");
margs.add("-pl", Util.join(changedModules, ",")); margs.add("-pl", Util.join(changedModules, ","));
} }
@ -527,18 +588,41 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
} }
margs.addTokenized(envVars.expand(project.getGoals())); margs.addTokenized(envVars.expand(project.getGoals()));
if (maven3orLater)
{
Builder builder = new Builder(slistener, proxies, project.sortedActiveModules, margs.toList(), envVars); Map<ModuleName,List<MavenReporter>> reporters = new HashMap<ModuleName, List<MavenReporter>>(project.sortedActiveModules.size());
MavenProbeAction mpa=null; for (MavenModule mavenModule : project.sortedActiveModules)
try { {
mpa = new MavenProbeAction(project,process.channel); reporters.put( mavenModule.getModuleName(), mavenModule.createReporters() );
addAction(mpa); }
r = process.call(builder); Maven3Builder maven3Builder = new Maven3Builder( slistener, proxies, reporters, margs.toList(), envVars );
return r; MavenProbeAction mpa=null;
} finally { try {
builder.end(launcher); mpa = new MavenProbeAction(project,process.channel);
getActions().remove(mpa); addAction(mpa);
process.discard(); 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 { } finally {
if (r != null) { if (r != null) {
@ -741,6 +825,9 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
@Override @Override
public Result call() throws IOException { public Result call() throws IOException {
try { try {
if (debug) {
listener.getLogger().println("Builder extends MavenBuilder in call " + Thread.currentThread().getContextClassLoader());
}
return super.call(); return super.call();
} finally { } finally {
if(lastProxy!=null) if(lastProxy!=null)
@ -748,6 +835,7 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
} }
} }
@Override @Override
void preBuild(MavenSession session, ReactorManager rm, EventDispatcher dispatcher) throws BuildFailureException, LifecycleExecutionException, IOException, InterruptedException { 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 // set all modules which are not actually being build (in incremental builds) to NOT_BUILD
@ -833,7 +921,15 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
throw new hudson.maven.agent.AbortException(r+" failed"); throw new hudson.maven.agent.AbortException(r+" failed");
} }
private static final long serialVersionUID = 1L; 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; private final boolean nonRecursive;
// We're called against the module root, not the workspace, which can cause a lot of confusion. // We're called against the module root, not the workspace, which can cause a lot of confusion.
private final String workspaceProper; private final String workspaceProper;
public PomParser(BuildListener listener, MavenInstallation mavenHome, MavenModuleSet project) { 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. // project cannot be shipped to the remote JVM, so all the relevant properties need to be captured now.
this.listener = listener; this.listener = listener;
@ -888,7 +983,6 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
this.privateRepository = null; this.privateRepository = null;
} }
this.alternateSettings = project.getAlternateSettings(); this.alternateSettings = project.getAlternateSettings();
} }
/** /**
@ -956,32 +1050,51 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
if (!settingsLoc.exists() && mrSettingsLoc.exists()) if (!settingsLoc.exists() && mrSettingsLoc.exists())
settingsLoc = mrSettingsLoc; settingsLoc = mrSettingsLoc;
} }
if (debug)
{
logger.println("use settingsLoc " + settingsLoc + " , privateRepository " + privateRepository);
}
if ((settingsLoc != null) && (!settingsLoc.exists())) { if ((settingsLoc != null) && (!settingsLoc.exists())) {
throw new AbortException(Messages.MavenModuleSetBuild_NoSuchAlternateSettings(settingsLoc.getAbsolutePath())); throw new AbortException(Messages.MavenModuleSetBuild_NoSuchAlternateSettings(settingsLoc.getAbsolutePath()));
} }
try { try {
MavenEmbedder embedder = MavenUtil. MavenEmbedderRequest mavenEmbedderRequest = new MavenEmbedderRequest( listener, mavenHome.getHomeDir(),
createEmbedder(listener, mavenHome.getHomeDir(), profiles, profiles, properties,
properties, privateRepository, settingsLoc); privateRepository, settingsLoc );
MavenProject mp = embedder.readProject(pom); mavenEmbedderRequest.setTransferListener( new SimpleTransferListener(listener) );
Map<MavenProject,String> relPath = new HashMap<MavenProject,String>(); MavenEmbedder embedder = MavenUtil.createEmbedder( mavenEmbedderRequest );
MavenUtil.resolveModules(embedder,mp,getRootPath(rootPOMRelPrefix),relPath,listener,nonRecursive);
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) { if(verbose) {
for (Entry<MavenProject, String> e : relPath.entrySet()) for (Entry<String,MavenProject> e : canonicalPaths.entrySet())
logger.printf("Discovered %s at %s\n",e.getKey().getId(),e.getValue()); logger.printf("Discovered %s at %s\n",e.getValue().getId(),e.getKey());
} }
List<PomInfo> infos = new ArrayList<PomInfo>(); Set<PomInfo> infos = new LinkedHashSet<PomInfo>();
toPomInfo(mp,null,relPath,infos); 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) for (PomInfo pi : infos)
pi.cutCycle(); pi.cutCycle();
embedder.stop(); return new ArrayList<PomInfo>(infos);
return infos;
} catch (MavenEmbedderException e) { } catch (MavenEmbedderException e) {
throw new MavenExecutionException(e); throw new MavenExecutionException(e);
} catch (ProjectBuildingException 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) { private void toPomInfo(MavenProject mp, PomInfo parent, Map<String,MavenProject> abslPath, Set<PomInfo> infos) throws IOException {
PomInfo pi = new PomInfo(mp, parent, relPath.get(mp)); 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); infos.add(pi);
for (MavenProject child : (List<MavenProject>)mp.getCollectedProjects()) for (String modulePath : mp.getModules())
toPomInfo(child,pi,relPath,infos); {
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; private static final long serialVersionUID = 1L;
@ -1004,10 +1134,60 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
/** /**
* Extra verbose debug switch. * Extra verbose debug switch.
*/ */
public static boolean debug = false; public static boolean debug = Boolean.getBoolean( "hudson.maven.debug" );
@Override @Override
public MavenModuleSet getParent() {// don't know why, but javac wants this public MavenModuleSet getParent() {// don't know why, but javac wants this
return super.getParent(); 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 static hudson.Util.fixNull;
import hudson.maven.agent.Main; import hudson.maven.agent.Main;
import hudson.maven.agent.Maven21Interceptor; import hudson.maven.agent.Maven21Interceptor;
import hudson.maven.agent.PluginManagerInterceptor;
import hudson.maven.ProcessCache.NewProcess; import hudson.maven.ProcessCache.NewProcess;
import hudson.model.BuildListener; import hudson.model.BuildListener;
import hudson.model.Computer; import hudson.model.Computer;
@ -169,7 +168,7 @@ final class MavenProcessFactory implements ProcessCache.Factory {
this.serverSocket = new ServerSocket(); this.serverSocket = new ServerSocket();
serverSocket.bind(null); // new InetSocketAddress(InetAddress.getLocalHost(),0)); serverSocket.bind(null); // new InetSocketAddress(InetAddress.getLocalHost(),0));
// prevent a hang at the accept method in case the forked process didn't start successfully // 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 { public Connection accept() throws IOException {
@ -200,6 +199,7 @@ final class MavenProcessFactory implements ProcessCache.Factory {
if(debug) if(debug)
listener.getLogger().println("Using env variables: "+ envVars); listener.getLogger().println("Using env variables: "+ envVars);
try { try {
//launcher.getChannel().export( type, instance )
final Acceptor acceptor = launcher.getChannel().call(new SocketHandler()); final Acceptor acceptor = launcher.getChannel().call(new SocketHandler());
Charset charset; Charset charset;
try { try {
@ -282,10 +282,14 @@ final class MavenProcessFactory implements ProcessCache.Factory {
args.addTokenized(getMavenOpts()); args.addTokenized(getMavenOpts());
args.add("-cp"); args.add( "-cp" );
args.add( String classPath =
(isMaster? Which.jarFile(Main.class).getAbsolutePath():slaveRoot.child("maven-agent.jar").getRemote())+ ( isMaster ? Which.jarFile( Main.class ).getAbsolutePath()
(launcher.isUnix()?":":";")+classWorldsJar); : slaveRoot.child( "maven-agent.jar" ).getRemote() )
+ ( launcher.isUnix() ? ":" : ";" )
+ ( isMaster ? classWorldsJar : slaveRoot.child( "classworlds.jar" ).getRemote() );
args.add( classPath );
//+classWorldsJar);
args.add(Main.class.getName()); args.add(Main.class.getName());
// M2_HOME // M2_HOME
@ -301,7 +305,7 @@ final class MavenProcessFactory implements ProcessCache.Factory {
// interceptor.jar // interceptor.jar
args.add(isMaster? args.add(isMaster?
Which.jarFile(PluginManagerInterceptor.class).getAbsolutePath(): Which.jarFile(hudson.maven.agent.AbortException.class).getAbsolutePath():
slaveRoot.child("maven-interceptor.jar").getRemote()); slaveRoot.child("maven-interceptor.jar").getRemote());
// TCP/IP port to establish the remoting infrastructure // TCP/IP port to establish the remoting infrastructure
@ -441,5 +445,8 @@ final class MavenProcessFactory implements ProcessCache.Factory {
debugPort = Integer.parseInt(port); 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()); private static final Logger LOGGER = Logger.getLogger(MavenProcessFactory.class.getName());
} }

View File

@ -25,32 +25,33 @@ package hudson.maven;
import hudson.AbortException; import hudson.AbortException;
import hudson.Util; import hudson.Util;
import hudson.model.BuildListener;
import hudson.model.TaskListener;
import hudson.model.AbstractProject;
import hudson.model.AbstractBuild; import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Hudson; import hudson.model.Hudson;
import hudson.model.TaskListener;
import hudson.tasks.Maven.MavenInstallation; import hudson.tasks.Maven.MavenInstallation;
import hudson.tasks.Maven.ProjectWithMaven; import hudson.tasks.Maven.ProjectWithMaven;
import org.apache.maven.embedder.MavenEmbedderException; import java.io.BufferedReader;
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.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Logger; 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 * @author Kohsuke Kawaguchi
*/ */
@ -107,12 +108,12 @@ public class MavenUtil {
systemProperties = ((MavenModuleSet) project).getMavenProperties(); systemProperties = ((MavenModuleSet) project).getMavenProperties();
} }
return createEmbedder(listener, return createEmbedder(new MavenEmbedderRequest(listener,
m!=null?m.getHomeDir():null, m!=null?m.getHomeDir():null,
profiles, profiles,
systemProperties, systemProperties,
privateRepository, privateRepository,
settingsLoc); settingsLoc ));
} }
public static MavenEmbedder createEmbedder(TaskListener listener, File mavenHome, String profiles) throws MavenEmbedderException, IOException { 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); return createEmbedder(listener,mavenHome,profiles,systemProperties,null);
} }
public static MavenEmbedder createEmbedder(TaskListener listener, File mavenHome, String profiles, Properties systemProperties, public static MavenEmbedder createEmbedder( TaskListener listener, File mavenHome, String profiles,
String privateRepository) throws MavenEmbedderException, IOException { Properties systemProperties, String privateRepository )
return createEmbedder(listener,mavenHome,profiles,systemProperties,privateRepository,null); throws MavenEmbedderException, IOException
{
return createEmbedder( new MavenEmbedderRequest( listener, mavenHome, profiles, systemProperties,
privateRepository, null ) );
} }
/** /**
* Creates a fresh {@link MavenEmbedder} instance. * 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, public static MavenEmbedder createEmbedder(MavenEmbedderRequest mavenEmbedderRequest) throws MavenEmbedderException, IOException {
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);
{ MavenRequest mavenRequest = new MavenRequest();
Enumeration<URL> e = cl.getResources("META-INF/plexus/components.xml");
while (e.hasMoreElements()) {
URL url = e.nextElement();
LOGGER.fine("components.xml from "+url);
}
}
// make sure ~/.m2 exists to avoid http://www.nabble.com/BUG-Report-tf3401736.html // make sure ~/.m2 exists to avoid http://www.nabble.com/BUG-Report-tf3401736.html
File m2Home = new File(MavenEmbedder.userHome, ".m2"); File m2Home = new File(MavenEmbedder.userHome, ".m2");
m2Home.mkdirs(); m2Home.mkdirs();
@ -169,22 +148,57 @@ public class MavenUtil {
throw new AbortException("Failed to create "+m2Home+ throw new AbortException("Failed to create "+m2Home+
"\nSee https://hudson.dev.java.net/cannot-create-.m2.html"); "\nSee https://hudson.dev.java.net/cannot-create-.m2.html");
if (privateRepository!=null) if (mavenEmbedderRequest.getPrivateRepository()!=null)
maven.setLocalRepositoryDirectory(new File(privateRepository)); 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);
maven.setSystemProperties(systemProperties); if ( mavenEmbedderRequest.getAlternateSettings() != null ) {
maven.start(); mavenRequest.setUserSettingsFile( mavenEmbedderRequest.getAlternateSettings().getAbsolutePath() );
} else {
mavenRequest.setUserSettingsFile( new File( m2Home, "settings.xml" ).getAbsolutePath() );
}
// 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; return maven;
} }
/** /**
* @deprecated MavenEmbedder has now a method to read all projects
* Recursively resolves module POMs that are referenced from * Recursively resolves module POMs that are referenced from
* the given {@link MavenProject} and parses them into * the given {@link MavenProject} and parses them into
* {@link MavenProject}s. * {@link MavenProject}s.
@ -198,39 +212,43 @@ public class MavenUtil {
* *
* @throws AbortException * @throws AbortException
* errors will be reported to the listener and the exception thrown. * errors will be reported to the listener and the exception thrown.
* @throws MavenEmbedderException
*/ */
public static void resolveModules(MavenEmbedder embedder, MavenProject project, public static void resolveModules( MavenEmbedder embedder, MavenProject project, String rel,
String rel, Map<MavenProject,String> relativePathInfo, Map<MavenProject, String> relativePathInfo, BuildListener listener,
BuildListener listener, boolean nonRecursive) throws ProjectBuildingException, boolean nonRecursive )
AbortException { throws ProjectBuildingException, AbortException, MavenEmbedderException
{
File basedir = project.getFile().getParentFile(); File basedir = project.getFile().getParentFile();
relativePathInfo.put(project,rel); relativePathInfo.put( project, rel );
if (!nonRecursive) { List<MavenProject> modules = new ArrayList<MavenProject>();
List<MavenProject> modules = new ArrayList<MavenProject>();
for (String modulePath : (List<String>) project.getModules()) { if ( !nonRecursive ) {
if (Util.fixEmptyAndTrim(modulePath)!=null) { for ( String modulePath : project.getModules()) {
File moduleFile = new File(basedir, modulePath); if ( Util.fixEmptyAndTrim( modulePath ) != null ) {
if (moduleFile.exists() && moduleFile.isDirectory()) { File moduleFile = new File( basedir, modulePath );
moduleFile = new File(basedir, modulePath + "/pom.xml"); 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"); if ( !moduleFile.exists() )
throw new AbortException( moduleFile + " is referenced from " + project.getFile()
+ " but it doesn't exist" );
String relativePath = rel; String relativePath = rel;
if(relativePath.length()>0) relativePath+='/'; if ( relativePath.length() > 0 )
relativePath+=modulePath; relativePath += '/';
relativePath += modulePath;
MavenProject child = embedder.readProject(moduleFile); MavenProject child = embedder.readProject( moduleFile );
resolveModules(embedder,child,relativePath,relativePathInfo,listener,nonRecursive); resolveModules( embedder, child, relativePath, relativePathInfo, listener, nonRecursive );
modules.add(child); modules.add( child );
} }
} }
}
project.setCollectedProjects(modules); project.setCollectedProjects( modules );
}
} }
/** /**
@ -306,10 +324,19 @@ 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. * 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()); 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.MojoExecution;
import org.apache.maven.plugin.Mojo; 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.configuration.PlexusConfiguration;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup; import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup;
@ -39,6 +42,7 @@ import java.lang.reflect.Proxy;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import hudson.util.InvocationInterceptor; import hudson.util.InvocationInterceptor;
import hudson.util.ReflectionUtils;
/** /**
* Information about Mojo to be executed. This object provides * Information about Mojo to be executed. This object provides
@ -127,12 +131,25 @@ public class MojoInfo {
PlexusConfiguration child = configuration.getChild(configName); PlexusConfiguration child = configuration.getChild(configName);
if(child==null) return null; // no such config 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); ConfigurationConverter converter = converterLookup.lookupConverterForType(type);
return type.cast(converter.fromConfiguration(converterLookup,child,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 // 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 // in this parameter, but we have no such type. So passing in a dummy
Object.class, Object.class,
mojoExecution.getMojoDescriptor().getPluginDescriptor().getClassRealm().getClassLoader(), cl,
expressionEvaluator)); expressionEvaluator));
} }

View File

@ -23,6 +23,7 @@
*/ */
package hudson.maven; package hudson.maven;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.model.CiManagement; import org.apache.maven.model.CiManagement;
import org.apache.maven.model.Dependency; import org.apache.maven.model.Dependency;
import org.apache.maven.model.Extension; import org.apache.maven.model.Extension;
@ -95,6 +96,16 @@ final class PomInfo implements Serializable {
*/ */
public final PomInfo parent; public final PomInfo parent;
/**
* maven groupId
*/
private final String groupId;
/**
* maven artifactId
*/
private final String artifactId;
public final Notifier mailNotifier; public final Notifier mailNotifier;
public PomInfo(MavenProject project, PomInfo parent, String relPath) { public PomInfo(MavenProject project, PomInfo parent, String relPath) {
@ -140,6 +151,9 @@ final class PomInfo implements Serializable {
this.mailNotifier = mailNotifier; this.mailNotifier = mailNotifier;
} else } else
this.mailNotifier = null; 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; 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; package hudson.maven;
import hudson.Launcher;
import hudson.Extension; import hudson.Extension;
import hudson.Launcher;
import hudson.Util; import hudson.Util;
import hudson.maven.reporters.MavenAbstractArtifactRecord; import hudson.maven.reporters.MavenAbstractArtifactRecord;
import hudson.model.AbstractBuild; import hudson.model.AbstractBuild;
@ -32,22 +32,32 @@ import hudson.model.AbstractProject;
import hudson.model.BuildListener; import hudson.model.BuildListener;
import hudson.model.Result; import hudson.model.Result;
import hudson.tasks.BuildStepDescriptor; import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher; import hudson.tasks.Publisher;
import hudson.tasks.Recorder; import hudson.tasks.Recorder;
import hudson.tasks.BuildStepMonitor;
import hudson.util.FormValidation; 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.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.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
/** /**
* {@link Publisher} for {@link MavenModuleSetBuild} to deploy artifacts * {@link Publisher} for {@link MavenModuleSetBuild} to deploy artifacts
@ -96,8 +106,8 @@ public class RedeployPublisher extends Recorder {
return true; return true;
} }
MavenAbstractArtifactRecord mar = getAction(build); List<MavenAbstractArtifactRecord> mars = getActions( build, listener );
if(mar==null) { if(mars==null || mars.isEmpty()) {
listener.getLogger().println("No artifacts are recorded. Is this a Maven project?"); listener.getLogger().println("No artifacts are recorded. Is this a Maven project?");
build.setResult(Result.FAILURE); build.setResult(Result.FAILURE);
return true; return true;
@ -108,16 +118,16 @@ public class RedeployPublisher extends Recorder {
MavenEmbedder embedder = MavenUtil.createEmbedder(listener,build); MavenEmbedder embedder = MavenUtil.createEmbedder(listener,build);
ArtifactRepositoryLayout layout = ArtifactRepositoryLayout layout =
(ArtifactRepositoryLayout) embedder.getContainer().lookup( ArtifactRepositoryLayout.ROLE,"default"); (ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.ROLE,"default");
ArtifactRepositoryFactory factory = ArtifactRepositoryFactory factory =
(ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE); (ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE);
ArtifactRepository repository = factory.createDeploymentArtifactRepository( final ArtifactRepository repository = factory.createDeploymentArtifactRepository(
id, url, layout, uniqueVersion); 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; return true;
} catch (MavenEmbedderException e) { } catch (MavenEmbedderException e) {
e.printStackTrace(listener.error(e.getMessage())); e.printStackTrace(listener.error(e.getMessage()));
@ -131,6 +141,8 @@ public class RedeployPublisher extends Recorder {
return true; return true;
} }
/** /**
* Obtains the {@link MavenAbstractArtifactRecord} that we'll work on. * Obtains the {@link MavenAbstractArtifactRecord} that we'll work on.
* <p> * <p>
@ -140,6 +152,23 @@ public class RedeployPublisher extends Recorder {
return build.getAction(MavenAbstractArtifactRecord.class); 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() { public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE; return BuildStepMonitor.NONE;
} }
@ -190,4 +219,126 @@ public class RedeployPublisher extends Recorder {
return FormValidation.ok(); 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.console.AnnotatedLargeText;
import hudson.maven.MavenEmbedder; import hudson.maven.MavenEmbedder;
import hudson.maven.MavenEmbedderException;
import hudson.maven.MavenUtil; import hudson.maven.MavenUtil;
import hudson.maven.RedeployPublisher.WrappedArtifactRepository;
import hudson.model.AbstractBuild; import hudson.model.AbstractBuild;
import hudson.model.AbstractProject; import hudson.model.AbstractProject;
import hudson.model.BallColor; import hudson.model.BallColor;
import hudson.model.BuildBadgeAction;
import hudson.model.Result; import hudson.model.Result;
import hudson.model.TaskAction; import hudson.model.TaskAction;
import hudson.model.TaskListener; import hudson.model.TaskListener;
import hudson.model.TaskThread; import hudson.model.TaskThread;
import hudson.model.BuildBadgeAction;
import hudson.model.TaskThread.ListenerAndText; import hudson.model.TaskThread.ListenerAndText;
import hudson.security.Permission;
import hudson.security.ACL; import hudson.security.ACL;
import hudson.security.Permission;
import hudson.util.Iterators; import hudson.util.Iterators;
import hudson.widgets.HistoryWidget; import hudson.widgets.HistoryWidget;
import hudson.widgets.HistoryWidget.Adapter; 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.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -60,6 +50,19 @@ import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.concurrent.CopyOnWriteArrayList; 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. * UI to redeploy artifacts after the fact.
* *
@ -204,16 +207,15 @@ public abstract class MavenAbstractArtifactRecord<T extends AbstractBuild<?,?>>
try { try {
MavenEmbedder embedder = MavenUtil.createEmbedder(listener,getBuild()); MavenEmbedder embedder = MavenUtil.createEmbedder(listener,getBuild());
ArtifactRepositoryLayout layout = ArtifactRepositoryLayout layout =
(ArtifactRepositoryLayout) embedder.getContainer().lookup( ArtifactRepositoryLayout.ROLE,"default"); (ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.class,"default");
ArtifactRepositoryFactory factory = ArtifactRepositoryFactory factory =
(ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE); (ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE);
ArtifactRepository repository = factory.createDeploymentArtifactRepository( ArtifactRepository repository = factory.createDeploymentArtifactRepository(
id, repositoryUrl, layout, uniqueVersion); id, repositoryUrl, layout, uniqueVersion);
WrappedArtifactRepository repo = new WrappedArtifactRepository(repository, uniqueVersion);
deploy(embedder,repo,listener);
deploy(embedder,repository,listener);
embedder.stop();
record.result = Result.SUCCESS; record.result = Result.SUCCESS;
} finally { } finally {
if(record.result==null) if(record.result==null)

View File

@ -26,20 +26,21 @@ package hudson.maven.reporters;
import hudson.maven.MavenAggregatedReport; import hudson.maven.MavenAggregatedReport;
import hudson.maven.MavenBuild; import hudson.maven.MavenBuild;
import hudson.maven.MavenEmbedder; import hudson.maven.MavenEmbedder;
import hudson.maven.MavenEmbedderException;
import hudson.maven.MavenModule; import hudson.maven.MavenModule;
import hudson.maven.MavenModuleSet; import hudson.maven.MavenModuleSet;
import hudson.maven.MavenModuleSetBuild; import hudson.maven.MavenModuleSetBuild;
import hudson.model.Action; import hudson.model.Action;
import hudson.model.TaskListener; 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.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; 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}. * 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.DefaultArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import com.google.common.collect.Maps;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.Map;
import java.util.logging.Logger; 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. // in the repository during deployment. So simulate that behavior if that's necessary.
final String canonicalExtension = canonicalName.substring(canonicalName.lastIndexOf('.')+1); final String canonicalExtension = canonicalName.substring(canonicalName.lastIndexOf('.')+1);
ArtifactHandler ah = handlerManager.getArtifactHandler(type); ArtifactHandler ah = handlerManager.getArtifactHandler(type);
// Fix for HUDSON-3814 - changed from comparing against canonical extension to canonicalName.endsWith. Map<String,ArtifactHandler> handlers = Maps.newHashMap();
if(!canonicalName.endsWith(ah.getExtension())) { handlers.put( type, new DefaultArtifactHandler(type) {
handlerManager.addHandlers(Collections.singletonMap(type,
new DefaultArtifactHandler(type) {
public String getExtension() { public String getExtension() {
return canonicalExtension; 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); 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.MavenAggregatedReport;
import hudson.maven.MavenBuild; import hudson.maven.MavenBuild;
import hudson.maven.MavenEmbedder; import hudson.maven.MavenEmbedder;
import hudson.maven.MavenEmbedderException;
import hudson.maven.MavenModule; import hudson.maven.MavenModule;
import hudson.maven.MavenModuleSetBuild; import hudson.maven.MavenModuleSetBuild;
import hudson.maven.MavenUtil;
import hudson.maven.RedeployPublisher.WrappedArtifactRepository;
import hudson.model.Action; import hudson.model.Action;
import hudson.model.TaskListener; 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.Artifact;
import org.apache.maven.artifact.deployer.ArtifactDeployer; import org.apache.maven.artifact.deployer.ArtifactDeployer;
import org.apache.maven.artifact.deployer.ArtifactDeploymentException; 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.ArtifactInstallationException;
import org.apache.maven.artifact.installer.ArtifactInstaller; import org.apache.maven.artifact.installer.ArtifactInstaller;
import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.embedder.MavenEmbedderException;
import org.apache.maven.project.artifact.ProjectArtifactMetadata; import org.apache.maven.project.artifact.ProjectArtifactMetadata;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException; 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. * {@link Action} that remembers {@link MavenArtifact artifact}s that are built.
* *
@ -105,33 +108,43 @@ public class MavenArtifactRecord extends MavenAbstractArtifactRecord<MavenBuild>
@Override @Override
public void deploy(MavenEmbedder embedder, ArtifactRepository deploymentRepository, TaskListener listener) throws MavenEmbedderException, IOException, ComponentLookupException, ArtifactDeploymentException { public void deploy(MavenEmbedder embedder, ArtifactRepository deploymentRepository, TaskListener listener) throws MavenEmbedderException, IOException, ComponentLookupException, ArtifactDeploymentException {
ArtifactHandlerManager handlerManager = (ArtifactHandlerManager) embedder.lookup(ArtifactHandlerManager.ROLE); ArtifactHandlerManager handlerManager = embedder.lookup(ArtifactHandlerManager.class);
ArtifactDeployer deployer = (ArtifactDeployer) embedder.lookup(ArtifactDeployer.ROLE);
ArtifactFactory factory = (ArtifactFactory) embedder.lookup(ArtifactFactory.ROLE);
PrintStream logger = listener.getLogger();
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); Artifact main = mainArtifact.toArtifact(handlerManager,factory,parent);
if(!isPOM()) if(!isPOM())
main.addMetadata(new ProjectArtifactMetadata(main,pomArtifact.getFile(parent))); main.addMetadata(new ProjectArtifactMetadata(main,pomArtifact.getFile(parent)));
// deploy the main artifact. This also deploys the POM // deploy the main artifact. This also deploys the POM
logger.println(Messages.MavenArtifact_DeployingMainArtifact(main.getFile().getName())); logger.println(Messages.MavenArtifact_DeployingMainArtifact(main.getFile().getName()));
deployer.deploy(main.getFile(),main,deploymentRepository,embedder.getLocalRepository()); deployMavenArtifact( main, deploymentRepository, embedder );
for (MavenArtifact aa : attachedArtifacts) { for (MavenArtifact aa : attachedArtifacts) {
Artifact a = aa.toArtifact(handlerManager,factory, parent); Artifact a = aa.toArtifact(handlerManager,factory, parent);
logger.println(Messages.MavenArtifact_DeployingAttachedArtifact(a.getFile().getName())); 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. * Installs the artifact to the local Maven repository.
*/ */
public void install(MavenEmbedder embedder) throws MavenEmbedderException, IOException, ComponentLookupException, ArtifactInstallationException { public void install(MavenEmbedder embedder) throws MavenEmbedderException, IOException, ComponentLookupException, ArtifactInstallationException {
ArtifactHandlerManager handlerManager = (ArtifactHandlerManager) embedder.lookup(ArtifactHandlerManager.ROLE); ArtifactHandlerManager handlerManager = embedder.lookup(ArtifactHandlerManager.class);
ArtifactInstaller installer = (ArtifactInstaller) embedder.lookup(ArtifactInstaller.class.getName()); ArtifactInstaller installer = embedder.lookup(ArtifactInstaller.class);
ArtifactFactory factory = (ArtifactFactory) embedder.lookup(ArtifactFactory.class.getName()); ArtifactFactory factory = embedder.lookup(ArtifactFactory.class);
Artifact main = mainArtifact.toArtifact(handlerManager,factory,parent); Artifact main = mainArtifact.toArtifact(handlerManager,factory,parent);
if(!isPOM()) if(!isPOM())

View File

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

View File

@ -26,7 +26,7 @@ Build=Byg
Maven\ Version=Maven version Maven\ Version=Maven version
Use\ private\ Maven\ repository=Benyt et privat Mavenarkiv Use\ private\ Maven\ repository=Benyt et privat Mavenarkiv
Incremental\ build\ -\ only\ build\ changed\ modules=Inkrementel byg - byg kun moduler med \u00e6ndringer 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 Goals\ and\ options=M\u00e5l og tilvalg
Build\ modules\ in\ parallel=Byg moduler i parallel Build\ modules\ in\ parallel=Byg moduler i parallel
Build\ Settings=Byggeindstillinger Build\ Settings=Byggeindstillinger

View File

@ -31,5 +31,5 @@ Use\ private\ Maven\ repository=Verwende privates Maven-Repository
Alternate\ settings\ file=Alternative Settings-Datei Alternate\ settings\ file=Alternative Settings-Datei
Build\ whenever\ a\ SNAPSHOT\ dependency\ is\ built=Baue dieses Projekt, wenn eine SNAPSHOT-Abhängigkeit gebaut wurde 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 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. 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # 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>. 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 Root\ POM=Fichero POM raíz
Build=Proyecto 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=Utilise un repository Maven priv\u00E9
Use\ private\ maven\ repository=Utiliser un repository Maven privé Use\ private\ maven\ repository=Utiliser un repository Maven privé
Goals\ and\ options=Goals et options 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>. 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 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 Build=\u30D3\u30EB\u30C9
Maven\ Version=\u4F7F\u7528\u3059\u308BMaven 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 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 Root\ POM=\u30EB\u30FC\u30C8POM
Goals\ and\ options=\u30B4\u30FC\u30EB\u3068\u30AA\u30D7\u30B7\u30E7\u30F3 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # 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. dramatisk behovet for konfiguration.

View File

@ -21,5 +21,5 @@
# THE SOFTWARE. # THE SOFTWARE.
body=\ 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. 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # 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. # THE SOFTWARE.
body=\ 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 # OUTDATED
body=\ 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 \ et diminue radicalement l''effort de configuration. Cette fonctionnalit\u00e9 est encore en b\u00eata mais elle est \
disponible afin d''obtenir vos retours. 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # 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. # THE SOFTWARE.
body=\ 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # 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. # THE SOFTWARE.
body=\ 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 \ uw nood aan configuratie drastisch reduceert. Merk op dat deze functionaliteit \
nog steeds in ontwikkeling is, maar al reeds beschikbaar gesteld wordt om \ nog steeds in ontwikkeling is, maar al reeds beschikbaar gesteld wordt om \
terugkoppeling te krijgen van gebruikers. terugkoppeling te krijgen van gebruikers.

View File

@ -22,6 +22,6 @@
# OUTDATED # OUTDATED
body=\ 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 \ reduz drasticamente a configura\u00e7\u00e3o. Ainda \u00e9 um trabalho em progresso, mas \
diposto a aceitar feedback. diposto a aceitar feedback.

View File

@ -21,4 +21,4 @@
# THE SOFTWARE. # THE SOFTWARE.
# OUTDATED # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # 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. # THE SOFTWARE.
# OUTDATED # 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. # THE SOFTWARE.
body=\ 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 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.DiscoveredModule=Discovered a new module {0} {1}
MavenModuleSetBuild.FailedToParsePom=Failed to parse POMs 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 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 MavenRedeployer.DisplayName=Deploy to Maven repository
ProcessCache.Reusing=Reusing existing maven process ProcessCache.Reusing=Reusing existing maven process

View File

@ -29,7 +29,7 @@ MavenBuilder.Aborted=Afbrudt
MavenBuilder.Failed=Maven stoppede med en fejl. MavenBuilder.Failed=Maven stoppede med en fejl.
MavenProbeAction.DisplayName=Overv\u00e5g Mavenproces MavenProbeAction.DisplayName=Overv\u00e5g Mavenproces
MavenProcessFactory.ClassWorldsNotFound=Ingen classworlds*.jar fundet i {0} -- Er dette et gyldigt maven2 direktorie? 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 MavenModule.Pronoun=Modul
MavenBuild.FailedEarlier=Bygget fejler f\u00f8r det n\u00e5r til dette 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? 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 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.DiscoveredModule=Se ha descubierto un nuevo módulo {0} {1}
MavenModuleSetBuild.FailedToParsePom=Error al analizar el fichero POM 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 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.DiscoveredModule=Un nouveau module {0} {1} a été trouvé
MavenModuleSetBuild.FailedToParsePom=Echec à la lecture des POMs 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 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 MavenRedeployer.DisplayName=Déployer vers un repository Maven
ProcessCache.Reusing=Réutilisation du process Maven existant 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 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.DiscoveredModule=\u65b0\u898f\u30e2\u30b8\u30e5\u30fc\u30eb {0} {1} \u3092\u767a\u898b
MavenModuleSetBuild.FailedToParsePom=POM\u306e\u89e3\u6790\u306b\u5931\u6557 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 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.DiscoveredModule= Een nieuwe module {0} {1} werd ontdekt.
MavenModuleSetBuild.FailedToParsePom=Het lezen van de POMs is gefaald. 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 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.DiscoveredModule=Descoberto um novo m\u00f3dulo {0} {1}
MavenModuleSetBuild.FailedToParsePom=Falhou ao analisar POMs 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 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.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 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 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.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 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 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.DiscoveredModule=Discovered a new module {0} {1}
MavenModuleSetBuild.FailedToParsePom=Failed to parse POMs 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>ui-samples-plugin</module>
<module>maven-agent</module> <module>maven-agent</module>
<module>maven-interceptor</module> <module>maven-interceptor</module>
<module>maven3-agent</module>
<module>maven3-interceptor</module>
<module>war</module> <module>war</module>
<module>test</module> <module>test</module>
<module>cli</module> <module>cli</module>
@ -94,29 +96,50 @@ THE SOFTWARE.
<version>1.39</version> <version>1.39</version>
</plugin> </plugin>
<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> <artifactId>maven-javadoc-plugin</artifactId>
<version>2.6.1</version> <version>2.6.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version> <version>2.3.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <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>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId> <artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version> <version>2.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version> <version>2.2-beta-5</version>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-resources-plugin</artifactId> <groupId>org.apache.maven.plugins</groupId>
<version>2.4.3</version> <artifactId>maven-resources-plugin</artifactId>
</plugin> <version>2.4.3</version>
</plugin>
<plugin> <plugin>
<!-- <!--
Both test harness and core uses stapler as an extension, Both test harness and core uses stapler as an extension,
@ -197,6 +220,7 @@ THE SOFTWARE.
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId> <artifactId>maven-enforcer-plugin</artifactId>
<version>1.0</version> <version>1.0</version>
<executions> <executions>
@ -258,9 +282,97 @@ THE SOFTWARE.
</dependency> </dependency>
</dependencies> </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> <properties>
<maven.version>2.0.9</maven.version> <mavenVersion>3.0.1</mavenVersion>
<maven.embedder.version>2.0.4</maven.embedder.version> <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, <!-- *.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. --> 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> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -357,6 +469,37 @@ THE SOFTWARE.
</plugins> </plugins>
</build> </build>
</profile> </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> </profiles>
<repositories> <repositories>
@ -370,6 +513,16 @@ THE SOFTWARE.
<enabled>false</enabled> <enabled>false</enabled>
</snapshots> </snapshots>
</repository> </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> </repositories>
<pluginRepositories> <pluginRepositories>

View File

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

View File

@ -40,6 +40,7 @@ THE SOFTWARE.
<properties> <properties>
<concurrency>1</concurrency> <!-- -1 means # of processors in the system --> <concurrency>1</concurrency> <!-- -1 means # of processors in the system -->
<mavenDebug>false</mavenDebug>
</properties> </properties>
<build> <build>
@ -70,6 +71,18 @@ THE SOFTWARE.
<name>hudson.ClassicPluginStrategy.useAntClassLoader</name> <name>hudson.ClassicPluginStrategy.useAntClassLoader</name>
<value>true</value> <value>true</value>
</property> </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> </systemProperties>
</configuration> </configuration>
</execution> </execution>

View File

@ -394,7 +394,15 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
* Returns the older default Maven, while still allowing specification of other bundled Mavens. * Returns the older default Maven, while still allowing specification of other bundled Mavens.
*/ */
protected MavenInstallation configureDefaultMaven() throws Exception { 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;
} }
/** /**
@ -402,6 +410,15 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
*/ */
protected MavenInstallation configureDefaultMaven(String mavenVersion, int mavenReqVersion) throws Exception { 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.. // 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"); String home = System.getProperty("maven.home");
if(home!=null) { if(home!=null) {
MavenInstallation mavenInstallation = new MavenInstallation("default",home, NO_PROPERTIES); 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."); "To avoid a performance hit, set the system property 'maven.home' to point to a Maven2 installation.");
FilePath mvn = hudson.getRootPath().createTempFile("maven", "zip"); FilePath mvn = hudson.getRootPath().createTempFile("maven", "zip");
mvn.copyFrom(HudsonTestCase.class.getClassLoader().getResource(mavenVersion + "-bin.zip")); mvn.copyFrom(HudsonTestCase.class.getClassLoader().getResource(mavenVersion + "-bin.zip"));
File mvnHome = createTmpDir(); File mvnHome = new File(buildDirectory);//createTmpDir();
mvn.unzip(new FilePath(mvnHome)); mvn.unzip(new FilePath(mvnHome));
// TODO: switch to tar that preserves file permissions more easily // TODO: switch to tar that preserves file permissions more easily
if(!Functions.isWindows()) if(!Functions.isWindows())
@ -1224,9 +1241,7 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
String dependencies = m.getMainAttributes().getValue("Plugin-Dependencies"); String dependencies = m.getMainAttributes().getValue("Plugin-Dependencies");
if(dependencies!=null) { if(dependencies!=null) {
MavenEmbedder embedder = new MavenEmbedder(null); MavenEmbedder embedder = new MavenEmbedder(getClass().getClassLoader(), null);
embedder.setClassLoader(getClass().getClassLoader());
embedder.start();
for( String dep : dependencies.split(",")) { for( String dep : dependencies.split(",")) {
String[] tokens = dep.split(":"); String[] tokens = dep.split(":");
String artifactId = tokens[0]; String artifactId = tokens[0];
@ -1264,7 +1279,6 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
FileUtils.copyFile(dependencyJar, dst); 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); configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject(); MavenModuleSet m = createMavenProject();
m.getReporters().add(new TestReporter()); m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod.zip"), m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource("maven-multimod.zip"),
getClass().getResource("maven-multimod-changes.zip"))); getClass().getResource("maven-multimod-changes.zip")));
buildAndAssertSuccess(m); buildAndAssertSuccess(m);
// Now run a second build with the changes. // Now run a second build with the changes.
m.setIncrementalBuild(true); m.setIncrementalBuild(true);
buildAndAssertSuccess(m); buildAndAssertSuccess(m);
MavenModuleSetBuild pBuild = m.getLastBuild(); MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet(); ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet()); assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) { for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString(); String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) { if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, 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")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
} }
long summedModuleDuration = 0; long summedModuleDuration = 0;
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) { for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
@ -75,39 +75,39 @@ public class MavenMultiModuleTest extends HudsonTestCase {
MavenModuleSet m = createMavenProject(); MavenModuleSet m = createMavenProject();
m.setRootPOM("parent/pom.xml"); m.setRootPOM("parent/pom.xml");
m.getReporters().add(new TestReporter()); 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"))); getClass().getResource("maven-multimod-changes.zip")));
buildAndAssertSuccess(m);
// Now run a second build with the changes.
m.setIncrementalBuild(true);
buildAndAssertSuccess(m); buildAndAssertSuccess(m);
MavenModuleSetBuild pBuild = m.getLastBuild(); // Now run a second build with the changes.
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet(); m.setIncrementalBuild(true);
buildAndAssertSuccess(m);
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet()); MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) { assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
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")) { if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, 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")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
} }
long summedModuleDuration = 0; long summedModuleDuration = 0;
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) { for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
summedModuleDuration += modBuild.getDuration(); summedModuleDuration += modBuild.getDuration();
} }
assertTrue("duration of moduleset build should be greater-equal than sum of the module builds", assertTrue("duration of moduleset build should be greater-equal than sum of the module builds",
pBuild.getDuration() >= summedModuleDuration); pBuild.getDuration() >= summedModuleDuration);
} }
@Bug(7684) @Bug(7684)
@ -116,33 +116,33 @@ public class MavenMultiModuleTest extends HudsonTestCase {
MavenModuleSet m = createMavenProject(); MavenModuleSet m = createMavenProject();
m.setRootPOM("../parent/pom.xml"); m.setRootPOM("../parent/pom.xml");
m.getReporters().add(new TestReporter()); 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"), getClass().getResource("maven-multimod-changes.zip"),
"moduleA")); "moduleA"));
buildAndAssertSuccess(m); buildAndAssertSuccess(m);
// Now run a second build with the changes. // Now run a second build with the changes.
m.setIncrementalBuild(true); m.setIncrementalBuild(true);
buildAndAssertSuccess(m); buildAndAssertSuccess(m);
MavenModuleSetBuild pBuild = m.getLastBuild(); MavenModuleSetBuild pBuild = m.getLastBuild();
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet(); ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet()); assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) { for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString(); String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) { if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, 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")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
} }
long summedModuleDuration = 0; long summedModuleDuration = 0;
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) { for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
@ -202,30 +202,30 @@ public class MavenMultiModuleTest extends HudsonTestCase {
public void testMultiModMavenNonRecursiveParsing() throws Exception { public void testMultiModMavenNonRecursiveParsing() throws Exception {
configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21); configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject(); MavenModuleSet m = createMavenProject();
m.setGoals("clean install -N"); m.setGoals("clean install -N");
m.getReporters().add(new TestReporter()); 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()) { for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString(); String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:multimod-top")) { if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:multimod-top")) {
assertEquals("moduleA should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleA should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleA")) {
assertEquals("moduleA should have Result.NOT_BUILT", Result.NOT_BUILT, 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")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleB")) {
assertEquals("moduleB should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult()); assertEquals("moduleB should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod:moduleC")) {
assertEquals("moduleC should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult()); 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); configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject(); MavenModuleSet m = createMavenProject();
m.getReporters().add(new TestReporter()); 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"))); 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()); assertBuildStatus(Result.UNSTABLE, m.scheduleBuild2(0).get());
MavenModuleSetBuild pBuild = m.getLastBuild(); // Now run a second build with the changes.
ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet(); m.setIncrementalBuild(true);
assertBuildStatus(Result.UNSTABLE, m.scheduleBuild2(0).get());
assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet()); MavenModuleSetBuild pBuild = m.getLastBuild();
assertEquals("Parent build should have Result.UNSTABLE", Result.UNSTABLE, pBuild.getResult()); ExtractChangeLogSet changeSet = (ExtractChangeLogSet) pBuild.getChangeSet();
for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) { assertFalse("ExtractChangeLogSet should not be empty.", changeSet.isEmptySet());
String parentModuleName = modBuild.getParent().getModuleName().toString(); assertEquals("Parent build should have Result.UNSTABLE", Result.UNSTABLE, pBuild.getResult());
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleA")) {
assertEquals("moduleA should have Result.UNSTABLE", Result.UNSTABLE, modBuild.getResult()); for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
} String parentModuleName = modBuild.getParent().getModuleName().toString();
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleB")) { if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleA")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleA should have Result.UNSTABLE", Result.UNSTABLE, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleC")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleB")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleD")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleC")) {
assertEquals("moduleD should have Result.NOT_BUILT", Result.NOT_BUILT, modBuild.getResult()); 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); configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject(); MavenModuleSet m = createMavenProject();
m.getReporters().add(new TestReporter()); 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()) { for (MavenBuild modBuild : pBuild.getModuleLastBuilds().values()) {
String parentModuleName = modBuild.getParent().getModuleName().toString(); String parentModuleName = modBuild.getParent().getModuleName().toString();
if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleA")) { if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleA")) {
assertEquals("moduleA should have Result.UNSTABLE", Result.UNSTABLE, modBuild.getResult()); assertEquals("moduleA should have Result.UNSTABLE", Result.UNSTABLE, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleB")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleB")) {
assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleB should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleC")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleC")) {
assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleC should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleD")) { else if (parentModuleName.equals("org.jvnet.hudson.main.test.multimod.incr:moduleD")) {
assertEquals("moduleD should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult()); assertEquals("moduleD should have Result.SUCCESS", Result.SUCCESS, modBuild.getResult());
} }
} }
} }
/* /*

View File

@ -24,6 +24,9 @@
package hudson.maven; package hudson.maven;
import hudson.model.Result; 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.Bug;
import org.jvnet.hudson.test.ExtractResourceSCM; import org.jvnet.hudson.test.ExtractResourceSCM;
import org.jvnet.hudson.test.HudsonTestCase; import org.jvnet.hudson.test.HudsonTestCase;
@ -31,6 +34,7 @@ import org.jvnet.hudson.test.SingleFileSCM;
import org.jvnet.hudson.test.Email; import org.jvnet.hudson.test.Email;
import java.io.File; import java.io.File;
import java.io.FilenameFilter;
/** /**
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
@ -99,12 +103,94 @@ 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()); 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) @Bug(3773)
public void testDeployUnstable() throws Exception { public void testDeployUnstable() throws Exception {
configureDefaultMaven(); configureDefaultMaven();
MavenModuleSet m2 = createMavenProject(); MavenModuleSet m2 = createMavenProject();
File repo = createTmpDir(); File repo = createTmpDir();
FileUtils.cleanDirectory( repo );
// a build with a failing unit tests // a build with a failing unit tests
m2.setScm(new ExtractResourceSCM(getClass().getResource("maven-test-failure-findbugs.zip"))); m2.setScm(new ExtractResourceSCM(getClass().getResource("maven-test-failure-findbugs.zip")));
m2.getPublishersList().add(new RedeployPublisher("",repo.toURI().toString(),false, true)); 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

@ -237,6 +237,26 @@ THE SOFTWARE.
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </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 --> <!-- offline profiler API when we need it -->
<!--dependency> <!--dependency>
<groupId>com.yourkit.api</groupId> <groupId>com.yourkit.api</groupId>