diff --git a/spring-boot-parent/pom.xml b/spring-boot-parent/pom.xml
index d1ecb8f34d..3bba723484 100644
--- a/spring-boot-parent/pom.xml
+++ b/spring-boot-parent/pom.xml
@@ -98,6 +98,11 @@
maven-settings-builder
${maven.version}
+
+ org.apache.maven.shared
+ maven-common-artifact-filters
+ 1.4
+
org.apache.maven.plugins
maven-shade-plugin
diff --git a/spring-boot-tools/spring-boot-maven-plugin/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/pom.xml
index 93b94ea879..47cb11090e 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/pom.xml
+++ b/spring-boot-tools/spring-boot-maven-plugin/pom.xml
@@ -126,6 +126,10 @@
org.apache.maven
maven-settings
+
+ org.apache.maven.shared
+ maven-common-artifact-filters
+
org.codehaus.plexus
plexus-archiver
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/pom.xml
new file mode 100644
index 0000000000..02747a078d
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ jar-exclude-artifact
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ repackage
+
+
+ servlet-api
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.4
+
+
+
+ Foo
+
+
+
+
+
+
+
+
+ org.springframework
+ spring-context
+ 3.2.3.RELEASE
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.0.1
+ provided
+
+
+ javax.servlet
+ servlet-api
+ 2.5
+ provided
+
+
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/src/main/java/org/test/SampleApplication.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..0b3b431677
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,8 @@
+package org.test;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/verify.groovy
new file mode 100644
index 0000000000..be667d6882
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-artifact/verify.groovy
@@ -0,0 +1,11 @@
+import java.io.*;
+import org.springframework.boot.maven.*;
+
+File f = new File( basedir, "target/jar-exclude-artifact-0.0.1.BUILD-SNAPSHOT.jar");
+new Verify.JarArchiveVerification(f, Verify.SAMPLE_APP) {
+ @Override
+ protected void verifyZipEntries(Verify.ArchiveVerifier verifier) throws Exception {
+ super.verifyZipEntries(verifier)
+ verifier.assertHasNoEntryNameStartingWith("lib/servlet-api-2.5.jar")
+ }
+}.verify();
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/pom.xml
new file mode 100644
index 0000000000..00bdeb2f85
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/pom.xml
@@ -0,0 +1,82 @@
+
+
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ jar-exclude-entry
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ repackage
+
+
+
+
+ javax.servlet
+ servlet-api
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.4
+
+
+
+ Foo
+
+
+
+
+
+
+
+
+ org.springframework
+ spring-context
+ 3.2.3.RELEASE
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.0.1
+ provided
+
+
+ javax.servlet
+ servlet-api
+ 2.5
+ provided
+
+
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/src/main/java/org/test/SampleApplication.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..0b3b431677
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,8 @@
+package org.test;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/verify.groovy
new file mode 100644
index 0000000000..4f27fc368d
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-entry/verify.groovy
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012-2014 the original author or authors.
+ *
+ * Licensed 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.*;
+import org.springframework.boot.maven.*;
+
+File f = new File( basedir, "target/jar-exclude-entry-0.0.1.BUILD-SNAPSHOT.jar");
+new Verify.JarArchiveVerification(f, Verify.SAMPLE_APP) {
+ @Override
+ protected void verifyZipEntries(Verify.ArchiveVerifier verifier) throws Exception {
+ super.verifyZipEntries(verifier)
+ verifier.assertHasNoEntryNameStartingWith("lib/servlet-api-2.5.jar")
+ }
+}.verify();
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/pom.xml
new file mode 100644
index 0000000000..c8bae6c3a7
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/pom.xml
@@ -0,0 +1,76 @@
+
+
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ jar-exclude-group
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ repackage
+
+
+ log4j
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.4
+
+
+
+ Foo
+
+
+
+
+
+
+
+
+ org.springframework
+ spring-context
+ 3.2.3.RELEASE
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.0.1
+ provided
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/src/main/java/org/test/SampleApplication.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..0b3b431677
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,8 @@
+package org.test;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/verify.groovy
new file mode 100644
index 0000000000..f03bbb3a83
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-exclude-group/verify.groovy
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012-2014 the original author or authors.
+ *
+ * Licensed 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.*;
+import org.springframework.boot.maven.*;
+
+File f = new File( basedir, "target/jar-exclude-group-0.0.1.BUILD-SNAPSHOT.jar");
+new Verify.JarArchiveVerification(f, Verify.SAMPLE_APP) {
+ @Override
+ protected void verifyZipEntries(Verify.ArchiveVerifier verifier) throws Exception {
+ super.verifyZipEntries(verifier)
+ verifier.assertHasNoEntryNameStartingWith("lib/log4j-1.2.17.jar")
+ }
+}.verify();
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/pom.xml
new file mode 100644
index 0000000000..1426be6b19
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ jar-test-scope
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ repackage
+
+
+ servlet-api
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.4
+
+
+
+ Foo
+
+
+
+
+
+
+
+
+ org.springframework
+ spring-context
+ 3.2.3.RELEASE
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.0.1
+ provided
+
+
+ log4j
+ log4j
+ 1.2.17
+ test
+
+
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/src/main/java/org/test/SampleApplication.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..0b3b431677
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,8 @@
+package org.test;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/verify.groovy
new file mode 100644
index 0000000000..b76415b150
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/jar-test-scope/verify.groovy
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012-2014 the original author or authors.
+ *
+ * Licensed 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.*;
+import org.springframework.boot.maven.*;
+
+File f = new File( basedir, "target/jar-test-scope-0.0.1.BUILD-SNAPSHOT.jar");
+new Verify.JarArchiveVerification(f, Verify.SAMPLE_APP) {
+ @Override
+ protected void verifyZipEntries(Verify.ArchiveVerifier verifier) throws Exception {
+ super.verifyZipEntries(verifier)
+ verifier.assertHasNoEntryNameStartingWith("lib/log4j-1.2.17.jar")
+ }
+}.verify();
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/pom.xml
new file mode 100644
index 0000000000..f48531ad0c
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/pom.xml
@@ -0,0 +1,56 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ run-exclude
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+ package
+
+ run
+
+
+
+
+ log4j
+ log4j
+
+
+ javax.servlet
+
+
+
+
+
+
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.0.1
+ provided
+
+
+ javax.servlet
+ servlet-api
+ 2.5
+ provided
+
+
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/src/main/java/org/test/SampleApplication.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..6f0d38785a
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,27 @@
+package org.test;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ if (isClassPresent("org.apache.log4j.Logger")) {
+ throw new IllegalStateException("Log4j was present and should not");
+ }
+ if (isClassPresent("javax.servlet.Servlet")) {
+ throw new IllegalStateException("servlet-api was present and should not");
+ }
+ System.out.println("I haz been run");
+ }
+
+ private static boolean isClassPresent(String className) {
+
+ try {
+ ClassLoader classLoader = SampleApplication.class.getClassLoader();
+ classLoader.loadClass(className);
+ return true;
+ }
+ catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/verify.groovy
new file mode 100644
index 0000000000..841c4a97de
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run-exclude/verify.groovy
@@ -0,0 +1,3 @@
+def file = new File(basedir, "build.log")
+return file.text.contains("I haz been run")
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/run/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/run/pom.xml
index af6bbbc2c7..092e362c67 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/it/run/pom.xml
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/run/pom.xml
@@ -16,7 +16,6 @@
@project.version@
-
package
run
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java
new file mode 100644
index 0000000000..954735dded
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2012-2014 the original author or authors.
+ *
+ * Licensed 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.
+ */
+
+package org.springframework.boot.maven;
+
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
+import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter;
+import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
+import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter;
+
+/**
+ * A base mojo filtering the dependencies of the project.
+ *
+ * @author Stephane Nicoll
+ * @since 1.1
+ */
+public abstract class AbstractDependencyFilterMojo extends AbstractMojo {
+
+ /**
+ * Collection of artifact definitions to exclude. The {@link Exclude}
+ * element defines a {@code groupId} and {@code artifactId} mandatory
+ * properties and an optional {@code classifier} property.
+ * @since 1.1
+ */
+ @Parameter
+ private List excludes;
+
+ /**
+ * Comma separated list of groupId names to exclude.
+ * @since 1.1
+ */
+ @Parameter(property = "excludeGroupIds", defaultValue = "")
+ protected String excludeGroupIds;
+
+ /**
+ * Comma separated list of artifact names to exclude.
+ * @since 1.1
+ */
+ @Parameter(property = "excludeArtifactIds", defaultValue = "")
+ protected String excludeArtifactIds;
+
+
+ protected void setExcludes(List excludes) {
+ this.excludes = excludes;
+ }
+
+ protected void setExcludeGroupIds(String excludeGroupIds) {
+ this.excludeGroupIds = excludeGroupIds;
+ }
+
+ protected void setExcludeArtifactIds(String excludeArtifactIds) {
+ this.excludeArtifactIds = excludeArtifactIds;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Set filterDependencies(Set dependencies, FilterArtifacts filters)
+ throws MojoExecutionException {
+ try {
+ return filters.filter(dependencies);
+ }
+ catch (ArtifactFilterException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ }
+
+ protected void initializeFilterArtifacts(FilterArtifacts filters) {
+ filters.addFilter(new ArtifactIdFilter("", cleanConfigItem(this.excludeArtifactIds)));
+ filters.addFilter(new GroupIdFilter("", cleanConfigItem(this.excludeGroupIds)));
+ if (this.excludes != null) {
+ filters.addFilter(new ExcludeFilter(this.excludes));
+ }
+ }
+
+
+ static String cleanConfigItem(String content) {
+ if (content == null || content.trim().isEmpty()) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ StringTokenizer st = new StringTokenizer(content, ",");
+ while (st.hasMoreElements()) {
+ String t = st.nextToken();
+ sb.append(t.trim());
+ if (st.hasMoreElements()) {
+ sb.append(",");
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java
new file mode 100644
index 0000000000..26642e4168
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012-2014 the original author or authors.
+ *
+ * Licensed 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.
+ */
+
+package org.springframework.boot.maven;
+
+import org.apache.maven.plugins.annotations.Parameter;
+
+/**
+ * A model for a dependency to exclude.
+ *
+ * @author Stephane Nicoll
+ * @since 1.1
+ */
+public class Exclude {
+
+ /**
+ * The groupId of the artifact to exclude.
+ */
+ @Parameter(required = true)
+ private String groupId;
+
+ /**
+ * The artifactId of the artifact to exclude.
+ */
+ @Parameter(required = true)
+ private String artifactId;
+
+ /**
+ * The classifier of the artifact to exclude
+ */
+ @Parameter
+ private String classifier;
+
+ 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 getClassifier() {
+ return classifier;
+ }
+
+ public void setClassifier(String classifier) {
+ this.classifier = classifier;
+ }
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ExcludeFilter.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ExcludeFilter.java
new file mode 100644
index 0000000000..523995346b
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ExcludeFilter.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2012-2014 the original author or authors.
+ *
+ * Licensed 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.
+ */
+
+package org.springframework.boot.maven;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactsFilter;
+import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
+
+/**
+ * An {@link org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter
+ * ArtifactsFilter} that filters out any artifact matching a configurable list
+ * of {@link Exclude} instances.
+ *
+ * @author Stephane Nicoll
+ * @since 1.1
+ */
+public class ExcludeFilter extends AbstractArtifactsFilter{
+
+ private final List excludes;
+
+ /**
+ * Create a new instance with the list of {@link Exclude}
+ * instance(s) to use.
+ */
+ public ExcludeFilter(List excludes) {
+ this.excludes = excludes;
+ }
+
+ @Override
+ public Set filter(Set artifacts) throws ArtifactFilterException {
+ Set result = new HashSet();
+ for (Object a : artifacts) {
+ Artifact artifact = (Artifact) a;
+ if (!matchExclude(artifact)) {
+ result.add(artifact);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Check if the specified {@link Artifact} matches one of the
+ * known excludes. Returns {@code true} if it should be excluded
+ */
+ private boolean matchExclude(Artifact artifact) {
+ for (Exclude exclude : excludes) {
+ if (match(artifact, exclude)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if the specified {@link Artifact} matches the specified
+ * {@link Exclude}. Returns {@code true} if it should be excluded
+ */
+ private boolean match(Artifact artifact, Exclude exclude) {
+ if (!exclude.getGroupId().equals(artifact.getGroupId())) {
+ return false;
+ }
+ if (!exclude.getArtifactId().equals(artifact.getArtifactId())) {
+ return false;
+ }
+ return exclude.getClassifier() == null ||
+ artifact.getClassifier() != null && exclude.getClassifier().equals(artifact.getClassifier());
+
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java
index c008a28b30..fee277d1a2 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java
@@ -18,9 +18,11 @@ package org.springframework.boot.maven;
import java.io.File;
import java.io.IOException;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.jar.JarFile;
+import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
@@ -31,6 +33,8 @@ import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
+import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
+
import org.springframework.boot.loader.tools.Layout;
import org.springframework.boot.loader.tools.Layouts;
import org.springframework.boot.loader.tools.Libraries;
@@ -46,7 +50,7 @@ import org.springframework.boot.loader.tools.Repackager;
* @author Stephane Nicoll
*/
@Mojo(name = "repackage", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
-public class RepackageMojo extends AbstractMojo {
+public class RepackageMojo extends AbstractDependencyFilterMojo {
private static final long FIND_WARNING_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
@@ -134,7 +138,12 @@ public class RepackageMojo extends AbstractMojo {
getLog().info("Layout: " + this.layout);
repackager.setLayout(this.layout.layout());
}
- Libraries libraries = new ArtifactsLibraries(this.project.getArtifacts());
+
+ FilterArtifacts filters = new FilterArtifacts();
+ initializeFilterArtifacts(filters);
+ Set artifacts = filterDependencies(this.project.getArtifacts(), filters);
+
+ Libraries libraries = new ArtifactsLibraries(artifacts);
try {
repackager.repackage(target, libraries);
}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java
index 434a44a882..6ea9857454 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java
@@ -24,10 +24,10 @@ import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Resource;
-import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Execute;
@@ -36,6 +36,9 @@ import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactFeatureFilter;
+import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
+
import org.springframework.boot.loader.tools.FileUtils;
import org.springframework.boot.loader.tools.JavaExecutable;
import org.springframework.boot.loader.tools.MainClassFinder;
@@ -43,13 +46,13 @@ import org.springframework.boot.loader.tools.RunProcess;
/**
* Run an executable archive application.
- *
+ *
* @author Phillip Webb
* @author Stephane Nicoll
*/
@Mojo(name = "run", requiresProject = true, defaultPhase = LifecyclePhase.VALIDATE, requiresDependencyResolution = ResolutionScope.TEST)
@Execute(phase = LifecyclePhase.TEST_COMPILE)
-public class RunMojo extends AbstractMojo {
+public class RunMojo extends AbstractDependencyFilterMojo {
private static final String SPRING_LOADED_AGENT_CLASSNAME = "org.springsource.loaded.agent.SpringLoadedAgent";
@@ -253,14 +256,27 @@ public class RunMojo extends AbstractMojo {
urls.add(this.classesDirectory.toURI().toURL());
}
- private void addDependencies(List urls) throws MalformedURLException {
- for (Artifact artifact : this.project.getArtifacts()) {
+ private void addDependencies(List urls) throws MalformedURLException, MojoExecutionException {
+ FilterArtifacts filters = new FilterArtifacts();
+ filters.addFilter(new TestArtifactFilter());
+ initializeFilterArtifacts(filters);
+
+ Set artifacts = filterDependencies(this.project.getArtifacts(), filters);
+ for (Artifact artifact : artifacts) {
if (artifact.getFile() != null) {
- if (!Artifact.SCOPE_TEST.equals(artifact.getScope())) {
- urls.add(artifact.getFile().toURI().toURL());
- }
+ urls.add(artifact.getFile().toURI().toURL());
}
}
}
+ private static class TestArtifactFilter extends AbstractArtifactFeatureFilter {
+ public TestArtifactFilter() {
+ super("", Artifact.SCOPE_TEST);
+ }
+
+ protected String getArtifactFeature(Artifact artifact) {
+ return artifact.getScope();
+ }
+ }
+
}
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/examples/exclude-dependency.apt.vm b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/examples/exclude-dependency.apt.vm
new file mode 100644
index 0000000000..77985559ed
--- /dev/null
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/examples/exclude-dependency.apt.vm
@@ -0,0 +1,117 @@
+ -----
+ Exclude a dependency
+ -----
+ Stephane Nicoll
+ -----
+ 2014-05-06
+ -----
+
+ By default, both the <<>> and the <<>> goals will include any <<>>
+ dependencies that are defined in the project. A boot-based project should consider
+ <<>> dependencies as <> dependencies that are required to run
+ the application.
+
+ Some of these dependencies may not be required at all and should be excluded from the
+ executable jar. For consistency, they should not be present either when running the
+ application.
+
+ There are tree ways one can exclude a dependency from being packaged/used at runtime
+
+ * Exclude a specific artifact identified by <<>> and <<>>
+ (optionnaly with a <<>> if needed)
+
+ * Exclude any artifact matching a given <<>>
+
+ * Exclude any artifact belonging to a given <<>>
+
+ []
+
+ The following excludes <<>> (and only that artifact)
+
+---
+
+ ...
+
+ ...
+
+ ...
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+
+
+
+ com.foo
+ bar
+
+
+
+ ...
+
+ ...
+
+ ...
+
+ ...
+
+---
+
+ This example excludes every artifacts having the <<>> or <<>>
+ artifact identifiers
+
+---
+
+ ...
+
+ ...
+
+ ...
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+
+
+ my-lib,another-lib
+
+
+ ...
+
+ ...
+
+ ...
+
+ ...
+
+---
+
+ Finally this example excludes any artifact belonging to the <<>> group
+
+
+---
+
+ ...
+
+ ...
+
+ ...
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+
+
+ com.foo
+
+
+ ...
+
+ ...
+
+ ...
+
+ ...
+
+---
+
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/examples/repackage-classifier.apt b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/examples/repackage-classifier.apt.vm
similarity index 100%
rename from spring-boot-tools/spring-boot-maven-plugin/src/site/apt/examples/repackage-classifier.apt
rename to spring-boot-tools/spring-boot-maven-plugin/src/site/apt/examples/repackage-classifier.apt.vm
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/index.apt b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/index.apt
index c820748c17..b7f2e3f412 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/index.apt
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/index.apt
@@ -38,6 +38,8 @@ Spring Boot Maven Plugin
* {{{./examples/repackage-classifier.html}Custom repackage classifier}}
+ * {{{./examples/exclude-dependency.html}Exclude a dependency}}
+
[]
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm
index 7b3e5c0d48..9afbd2544e 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm
@@ -4,7 +4,7 @@
-----
Stephane Nicoll
-----
- 2014-05-02
+ 2014-05-06
-----
Usage
@@ -40,9 +40,13 @@ Usage
---
- The example above repackages a jar or war that is built during the package phase of the Maven lifecycle. The
- original (i.e. non exectuable) artifact is renamed to <<<.original>>> by default but it is also possible to
- keep the original artifact using a custom classifier.
+ The example above repackages a jar or war that is built during the package phase of the Maven lifecycle,
+ including any <<>> dependencies that are defined in the project. If some of these dependencies
+ need to be excluded, you can use one of the exclude options,
+ see {{{./examples/exclude-dependency.html}Exclude a dependency}} for more details.
+
+ The original (i.e. non exectuable) artifact is renamed to <<<.original>>> by default but it is also
+ possible to keep the original artifact using a custom classifier.
The plugin rewrites your manifest, and in particular it manages the <> and <>
entries, so if the defaults don't work you have to configure those there (not in the jar plugin). The
@@ -82,6 +86,8 @@ Usage
* {{{./examples/repackage-classifier.html}Custom repackage classifier}}
+ * {{{./examples/exclude-dependency.html}Exclude a dependency}}
+
[]
* Running the application
@@ -120,4 +126,9 @@ mvn spring-boot:run
...
----
\ No newline at end of file
+---
+
+ In order to be consistent with the <<>> goal, the <<>> goal builds the classpath
+ in such a way that any dependency that is excluded in the plugin's configuration gets excluded
+ from the classpath as well. See {{{./examples/exclude-dependency.html}Exclude a dependency}} for
+ more details.
\ No newline at end of file
diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/site/site.xml b/spring-boot-tools/spring-boot-maven-plugin/src/site/site.xml
index 73c82ec306..93cddec5b7 100644
--- a/spring-boot-tools/spring-boot-maven-plugin/src/site/site.xml
+++ b/spring-boot-tools/spring-boot-maven-plugin/src/site/site.xml
@@ -8,6 +8,7 @@