diff --git a/pom.xml b/pom.xml
index fb076cdc..27a0b125 100644
--- a/pom.xml
+++ b/pom.xml
@@ -168,6 +168,11 @@
commons-exec
1.3
+
+ org.apache.maven.shared
+ maven-common-artifact-filters
+ 3.0.0
+
org.apache.maven.shared
diff --git a/src/main/java/org/codehaus/mojo/exec/AbstractExecMojo.java b/src/main/java/org/codehaus/mojo/exec/AbstractExecMojo.java
index 0899b53b..12c2a0b4 100644
--- a/src/main/java/org/codehaus/mojo/exec/AbstractExecMojo.java
+++ b/src/main/java/org/codehaus/mojo/exec/AbstractExecMojo.java
@@ -20,20 +20,24 @@
*/
import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.apache.maven.artifact.Artifact;
-import org.apache.maven.model.Resource;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;
import org.codehaus.plexus.util.cli.CommandLineUtils;
/**
@@ -140,6 +144,17 @@ public abstract class AbstractExecMojo
*/
@Parameter( property = "addOutputToClasspath", defaultValue = "true" )
private boolean addOutputToClasspath;
+
+
+ /**
+ * List of dependencies to exclude from the test classpath. Each dependency string must follow the format
+ * groupId:artifactId. For example: org.acme:project-a
+ *
+ * @since 1.5.1
+ */
+ @Parameter( property = "exec.classpathDependencyExcludes" )
+ private String[] classpathDependencyExcludes;
+
/**
* Collects the project artifacts in the specified List and the project specific classpath (build output and build
@@ -192,10 +207,44 @@ else if ( "system".equals( classpathScope ) )
{
throw new IllegalStateException( "Invalid classpath scope: " + classpathScope );
}
-
+
getLog().debug( "Collected project artifacts " + artifacts );
+ //filter dependency
+ if ( classpathDependencyExcludes != null )
+ {
+ ArtifactFilter dependencyFilter =
+ new PatternIncludesArtifactFilter( Arrays.asList( classpathDependencyExcludes ) );
+ List filterList = this.filterArtifacts( artifacts, dependencyFilter );
+ artifacts.clear();
+ artifacts.addAll(filterList);
+ getLog().debug( "Collected project artifacts after filter " + artifacts );
+ }
+
+
getLog().debug( "Collected project classpath " + theClasspathFiles );
}
+
+ /**
+ * Return a new set containing only the artifacts accepted by the given filter.
+ *
+ * @param artifacts The unfiltered artifacts
+ * @param filter The filter to apply
+ * @return The filtered result
+ */
+ private List filterArtifacts( List artifacts, ArtifactFilter filter )
+ {
+ List filteredArtifacts = new ArrayList();
+
+ for ( Artifact artifact : artifacts )
+ {
+ if ( !filter.include( artifact ) )
+ {
+ filteredArtifacts.add( artifact );
+ }
+ }
+
+ return filteredArtifacts;
+ }
/**
* Parses the argument string given by the user. Strings are recognized as everything between STRING_WRAPPER.
diff --git a/src/test/java/org/codehaus/mojo/exec/ExecJavaMojoTest.java b/src/test/java/org/codehaus/mojo/exec/ExecJavaMojoTest.java
index 33389de6..1c26ae2c 100644
--- a/src/test/java/org/codehaus/mojo/exec/ExecJavaMojoTest.java
+++ b/src/test/java/org/codehaus/mojo/exec/ExecJavaMojoTest.java
@@ -18,6 +18,8 @@
import java.io.File;
import java.io.PrintStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.DefaultArtifactRepository;
@@ -135,6 +137,32 @@ public void testWaitNoDaemonThreads()
assertEquals( MainWithThreads.ALL_EXITED, output.trim() );
}
+
+
+
+ public void testClasspathDependencyExcludes()
+ throws Exception
+ {
+ File pom = new File( getBasedir(), "src/test/projects/project15/pom.xml" );
+ String output = executeDebug( pom, "java" );
+ String expectedExcludeDependency = "commons-logging:commons-logging";
+
+ Pattern pattern = Pattern.compile(".*?Collected project artifacts \\[(.*?)\\].*");
+ Matcher matcher = pattern.matcher(output.trim());
+ String result = expectedExcludeDependency;
+ //check it present in project dependency
+ if(matcher.find()){
+ pattern = Pattern.compile(".*?Collected project artifacts after filter \\[(.*?)\\].*");
+ matcher = pattern.matcher(output.trim());
+ //check it present after filter
+ if(matcher.find()){
+ result = matcher.group(0);
+ }
+ }
+
+ assertFalse(result.contains(expectedExcludeDependency) );
+ }
+
/**
* For cases where the Java code spawns Threads and main returns soon, but code contains non interruptible threads.
@@ -235,6 +263,52 @@ private String execute( File pom, String goal )
return stringOutputStream.toString();
}
+
+
+ /**
+ * @return output from System.out during mojo execution
+ */
+ private String executeDebug( File pom, String goal )
+ throws Exception
+ {
+
+ ExecJavaMojo mojo;
+ mojo = (ExecJavaMojo) lookupMojo( goal, pom );
+
+ setUpProject( pom, mojo );
+
+ MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
+
+ // why isn't this set up by the harness based on the default-value? TODO get to bottom of this!
+ setVariableValueToObject( mojo, "includeProjectDependencies", Boolean.TRUE );
+ setVariableValueToObject( mojo, "killAfter", (long) -1 );
+ setVariableValueToObject( mojo, "cleanupDaemonThreads", Boolean.TRUE );
+ setVariableValueToObject( mojo, "classpathScope", "compile" );
+
+ assertNotNull( mojo );
+ assertNotNull( project );
+
+ // trap System.out
+ PrintStream out = System.out;
+ StringOutputStream stringOutputStream = new StringOutputStream();
+ System.setOut( new PrintStream( stringOutputStream ) );
+ // ensure we don't log unnecessary stuff which would interfere with assessing success of tests
+ mojo.setLog( new DefaultLog( new ConsoleLogger( Logger.LEVEL_DEBUG, "exec:java" ) ) );
+
+ try
+ {
+ mojo.execute();
+ }
+ finally
+ {
+ // see testUncooperativeThread() for explaination
+ Thread.sleep( 300 ); // time seems about right
+ System.setOut( out );
+ }
+
+ return stringOutputStream.toString();
+ }
+
private void setUpProject( File pomFile, AbstractMojo mojo )
throws Exception
diff --git a/src/test/projects/project15/pom.xml b/src/test/projects/project15/pom.xml
new file mode 100644
index 00000000..2c421706
--- /dev/null
+++ b/src/test/projects/project15/pom.xml
@@ -0,0 +1,88 @@
+
+ 4.0.0
+ org.cb.maven.plugins.exec
+ project15
+ 0.1
+ jar
+ Maven Exec Plugin
+ Test that one can force adding the test-classpath for the java mojo
+
+ 2005
+
+
+ Apache License 2
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+
+
+
+
+
+ Jerome Lacoste
+ jerome
+ jerome@coffeebreaks.org
+ CoffeeBreaks
+ http://www.coffeebreaks.org
+
+ Java Developer
+
+ +1
+
+
+
+
+
+ commons-io
+ commons-io
+ 1.1
+
+
+ commons-logging
+ commons-logging
+ 1.0.4
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ test
+
+ java
+
+
+
+
+ true
+
+ commons-logging:commons-logging
+
+ org.codehaus.mojo.exec.DummyMain
+ -X
+
+ -X
+
+
+
+
+
+
+
+