You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2026/10/13 21:31:48 UTC
(maven-dependency-plugin) 01/01: [MDEP-588] Add excludeOptional and excludeReactor to the dependency filter mojos
This is an automated email from the ASF dual-hosted git repository.
slachiewicz pushed a commit to branch agent/filter-optional-reactor
in repository https://gitbox.apache.org/repos/asf/maven-dependency-plugin.git
commit 9877601704cef5ce0d4f96e1e57147de96cf8a9b
Author: Sylwester Lachiewicz <sl...@apache.org>
AuthorDate: Tue Oct 13 23:11:12 2026 +0200
[MDEP-588] Add excludeOptional and excludeReactor to the dependency filter mojos
---
.../mdep-588-exclude-optional/invoker.properties | 18 +++++
src/it/projects/mdep-588-exclude-optional/pom.xml | 75 +++++++++++++++++++++
.../mdep-588-exclude-optional/verify.groovy | 28 ++++++++
.../mdep-589-exclude-reactor/child-a/pom.xml | 31 +++++++++
.../child-a/src/main/resources/DoNotDelete.xml | 20 ++++++
.../mdep-589-exclude-reactor/child-b/pom.xml | 76 ++++++++++++++++++++++
.../mdep-589-exclude-reactor/invoker.properties | 18 +++++
src/it/projects/mdep-589-exclude-reactor/pom.xml | 36 ++++++++++
.../mdep-589-exclude-reactor/verify.groovy | 28 ++++++++
.../AbstractDependencyFilterMojo.java | 28 ++++++++
.../filters/ExcludeOptionalArtifactsFilter.java | 45 +++++++++++++
.../examples/copying-project-dependencies.md.vm | 68 +++++++++++++++++++
.../fromDependencies/TestCopyDependenciesMojo.java | 52 +++++++++++++++
13 files changed, 523 insertions(+)
diff --git a/src/it/projects/mdep-588-exclude-optional/invoker.properties b/src/it/projects/mdep-588-exclude-optional/invoker.properties
new file mode 100644
index 00000000..101be4e9
--- /dev/null
+++ b/src/it/projects/mdep-588-exclude-optional/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals = clean process-sources
diff --git a/src/it/projects/mdep-588-exclude-optional/pom.xml b/src/it/projects/mdep-588-exclude-optional/pom.xml
new file mode 100644
index 00000000..3cf90844
--- /dev/null
+++ b/src/it/projects/mdep-588-exclude-optional/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.its.dependency</groupId>
+ <artifactId>mdep-588-exclude-optional</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <description>copy-dependencies with excludeOptional must skip optional dependencies (MDEP-588, MDEP-661).</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.dependency</groupId>
+ <artifactId>ResourceArtifact</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.dependency</groupId>
+ <artifactId>ResourceArtifact</artifactId>
+ <version>1.0</version>
+ <classifier>client</classifier>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>default</id>
+ <phase>process-sources</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/default</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>exclude-optional</id>
+ <phase>process-sources</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <excludeOptional>true</excludeOptional>
+ <outputDirectory>${project.build.directory}/exclude-optional</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/it/projects/mdep-588-exclude-optional/verify.groovy b/src/it/projects/mdep-588-exclude-optional/verify.groovy
new file mode 100644
index 00000000..c235a6d1
--- /dev/null
+++ b/src/it/projects/mdep-588-exclude-optional/verify.groovy
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+File all = new File( basedir, 'target/default' )
+assert new File( all, 'ResourceArtifact-1.0.jar' ).isFile()
+assert new File( all, 'ResourceArtifact-1.0-client.jar' ).isFile()
+
+File withoutOptional = new File( basedir, 'target/exclude-optional' )
+assert new File( withoutOptional, 'ResourceArtifact-1.0.jar' ).isFile()
+assert !new File( withoutOptional, 'ResourceArtifact-1.0-client.jar' ).exists()
+
+return true
diff --git a/src/it/projects/mdep-589-exclude-reactor/child-a/pom.xml b/src/it/projects/mdep-589-exclude-reactor/child-a/pom.xml
new file mode 100644
index 00000000..39aa47fb
--- /dev/null
+++ b/src/it/projects/mdep-589-exclude-reactor/child-a/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.dependency</groupId>
+ <artifactId>mdep-589-exclude-reactor</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>child-a</artifactId>
+</project>
diff --git a/src/it/projects/mdep-589-exclude-reactor/child-a/src/main/resources/DoNotDelete.xml b/src/it/projects/mdep-589-exclude-reactor/child-a/src/main/resources/DoNotDelete.xml
new file mode 100644
index 00000000..4d3d9e49
--- /dev/null
+++ b/src/it/projects/mdep-589-exclude-reactor/child-a/src/main/resources/DoNotDelete.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<root/>
diff --git a/src/it/projects/mdep-589-exclude-reactor/child-b/pom.xml b/src/it/projects/mdep-589-exclude-reactor/child-b/pom.xml
new file mode 100644
index 00000000..4ec44553
--- /dev/null
+++ b/src/it/projects/mdep-589-exclude-reactor/child-b/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.dependency</groupId>
+ <artifactId>mdep-589-exclude-reactor</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>child-b</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.dependency</groupId>
+ <artifactId>child-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.dependency</groupId>
+ <artifactId>ResourceArtifact</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>default</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/default</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>exclude-reactor</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <excludeReactor>true</excludeReactor>
+ <outputDirectory>${project.build.directory}/exclude-reactor</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/it/projects/mdep-589-exclude-reactor/invoker.properties b/src/it/projects/mdep-589-exclude-reactor/invoker.properties
new file mode 100644
index 00000000..a644cb7e
--- /dev/null
+++ b/src/it/projects/mdep-589-exclude-reactor/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals = clean package
diff --git a/src/it/projects/mdep-589-exclude-reactor/pom.xml b/src/it/projects/mdep-589-exclude-reactor/pom.xml
new file mode 100644
index 00000000..b7f50efb
--- /dev/null
+++ b/src/it/projects/mdep-589-exclude-reactor/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.dependency</groupId>
+ <artifactId>mdep-589-exclude-reactor</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <description>copy-dependencies with excludeReactor must skip dependencies that are reactor projects (MDEP-589).</description>
+
+ <modules>
+ <module>child-a</module>
+ <module>child-b</module>
+ </modules>
+</project>
diff --git a/src/it/projects/mdep-589-exclude-reactor/verify.groovy b/src/it/projects/mdep-589-exclude-reactor/verify.groovy
new file mode 100644
index 00000000..c6ccb98d
--- /dev/null
+++ b/src/it/projects/mdep-589-exclude-reactor/verify.groovy
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+File all = new File( basedir, 'child-b/target/default' )
+assert new File( all, 'child-a-1.0-SNAPSHOT.jar' ).isFile()
+assert new File( all, 'ResourceArtifact-1.0.jar' ).isFile()
+
+File withoutReactor = new File( basedir, 'child-b/target/exclude-reactor' )
+assert !new File( withoutReactor, 'child-a-1.0-SNAPSHOT.jar' ).exists()
+assert new File( withoutReactor, 'ResourceArtifact-1.0.jar' ).isFile()
+
+return true
diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java
index a483519a..8079e391 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java
@@ -36,9 +36,11 @@ import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.dependency.AbstractDependencyMojo;
+import org.apache.maven.plugins.dependency.resolvers.ExcludeReactorProjectsArtifactFilter;
import org.apache.maven.plugins.dependency.utils.DependencyStatusSets;
import org.apache.maven.plugins.dependency.utils.DependencyUtil;
import org.apache.maven.plugins.dependency.utils.ResolverUtil;
+import org.apache.maven.plugins.dependency.utils.filters.ExcludeOptionalArtifactsFilter;
import org.apache.maven.plugins.dependency.utils.translators.ArtifactTranslator;
import org.apache.maven.plugins.dependency.utils.translators.ClassifierTypeTranslator;
import org.apache.maven.project.DefaultProjectBuildingRequest;
@@ -101,6 +103,24 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj
@Parameter(property = "excludeTransitive", defaultValue = "false")
protected boolean excludeTransitive;
+ /**
+ * If we should exclude optional dependencies, that is artifacts for which
+ * {@link Artifact#isOptional()} is {@code true}.
+ *
+ * @since 3.12.0
+ */
+ @Parameter(property = "excludeOptional", defaultValue = "false")
+ protected boolean excludeOptional;
+
+ /**
+ * If we should exclude artifacts that are projects of the current reactor build, matched by groupId,
+ * artifactId and version.
+ *
+ * @since 3.12.0
+ */
+ @Parameter(property = "excludeReactor", defaultValue = "false")
+ protected boolean excludeReactor;
+
/**
* Comma-separated list of Types to include. Empty String indicates include everything (default).
*
@@ -339,6 +359,14 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj
DependencyUtil.cleanToBeTokenizedString(this.includeArtifactIds),
DependencyUtil.cleanToBeTokenizedString(this.excludeArtifactIds)));
+ if (excludeOptional) {
+ filter.addFilter(new ExcludeOptionalArtifactsFilter());
+ }
+
+ if (excludeReactor) {
+ filter.addFilter(new ExcludeReactorProjectsArtifactFilter(session.getProjects(), getLog()));
+ }
+
// start with all artifacts.
Set<Artifact> artifacts;
diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/filters/ExcludeOptionalArtifactsFilter.java b/src/main/java/org/apache/maven/plugins/dependency/utils/filters/ExcludeOptionalArtifactsFilter.java
new file mode 100644
index 00000000..f19948db
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/dependency/utils/filters/ExcludeOptionalArtifactsFilter.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+package org.apache.maven.plugins.dependency.utils.filters;
+
+import java.util.LinkedHashSet;
+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;
+
+/**
+ * Filter that removes optional artifacts, that is artifacts for which {@link Artifact#isOptional()} is {@code true}.
+ *
+ * @since 3.12.0
+ */
+public class ExcludeOptionalArtifactsFilter extends AbstractArtifactsFilter {
+
+ @Override
+ public Set<Artifact> filter(Set<Artifact> artifacts) throws ArtifactFilterException {
+ Set<Artifact> result = new LinkedHashSet<>();
+ for (Artifact artifact : artifacts) {
+ if (!artifact.isOptional()) {
+ result.add(artifact);
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/site/markdown/examples/copying-project-dependencies.md.vm b/src/site/markdown/examples/copying-project-dependencies.md.vm
index b82c99de..c9d75531 100644
--- a/src/site/markdown/examples/copying-project-dependencies.md.vm
+++ b/src/site/markdown/examples/copying-project-dependencies.md.vm
@@ -96,6 +96,74 @@ As mentioned, [transitive dependencies](https://maven.apache.org/guides/introduc
</project>
```
+Excluding optional dependencies
+-------------------------------
+
+Dependencies declared with `<optional>true</optional>` are copied by default. Set the `excludeOptional` property to **true** to leave them out, for example when they are only needed to compile against and must not be shipped.
+
+```xml
+<project>
+ [...]
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>${project.version}</version>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${esc.d}{project.build.directory}/alternateLocation</outputDirectory>
+ <excludeOptional>true</excludeOptional>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ [...]
+</project>
+```
+
+Excluding reactor projects
+--------------------------
+
+When the project depends on artifacts that are themselves projects of the current reactor build, their jars are copied like any other dependency. Set the `excludeReactor` property to **true** to skip them, for example to build a class path that does not contain classes that are already in the reactor project's `target/classes`. Artifacts are matched to reactor projects by groupId, artifactId and version.
+
+```xml
+<project>
+ [...]
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>${project.version}</version>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${esc.d}{project.build.directory}/alternateLocation</outputDirectory>
+ <excludeReactor>true</excludeReactor>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ [...]
+</project>
+```
+
Subtrees
--------
diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo.java
index 83715c63..4e239fe3 100644
--- a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo.java
+++ b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo.java
@@ -24,6 +24,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -41,6 +42,7 @@ import org.apache.maven.plugins.dependency.utils.CopyUtil;
import org.apache.maven.plugins.dependency.utils.DependencyUtil;
import org.apache.maven.plugins.dependency.utils.markers.DefaultFileMarkerHandler;
import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.FileUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -51,7 +53,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
@MojoTest(realRepositorySession = true)
class TestCopyDependenciesMojo {
@@ -437,6 +441,54 @@ class TestCopyDependenciesMojo {
}
}
+ @Test
+ @InjectMojo(goal = "copy-dependencies")
+ void testExcludeOptional(CopyDependenciesMojo mojo) throws Exception {
+ Set<Artifact> artifacts = stubFactory.getScopedArtifacts();
+ Artifact optional = artifacts.iterator().next();
+ optional.setOptional(true);
+ mojo.getProject().setArtifacts(artifacts);
+
+ // default keeps optional dependencies
+ mojo.execute();
+ assertTrue(new File(mojo.outputDirectory, DependencyUtil.getFormattedFileName(optional, false)).exists());
+ FileUtils.deleteDirectory(mojo.outputDirectory);
+
+ mojo.excludeOptional = true;
+ mojo.execute();
+
+ for (Artifact artifact : artifacts) {
+ File file = new File(mojo.outputDirectory, DependencyUtil.getFormattedFileName(artifact, false));
+ assertEquals(artifact != optional, file.exists(), artifact.getId());
+ }
+ }
+
+ @Test
+ @InjectMojo(goal = "copy-dependencies")
+ void testExcludeReactor(CopyDependenciesMojo mojo) throws Exception {
+ Set<Artifact> artifacts = stubFactory.getScopedArtifacts();
+ Artifact reactorArtifact = artifacts.iterator().next();
+ mojo.getProject().setArtifacts(artifacts);
+
+ MavenProject reactorProject = mock(MavenProject.class);
+ when(reactorProject.getArtifact()).thenReturn(reactorArtifact);
+ doReturn(Collections.singletonList(reactorProject)).when(session).getProjects();
+
+ // default keeps artifacts that are reactor projects
+ mojo.execute();
+ assertTrue(
+ new File(mojo.outputDirectory, DependencyUtil.getFormattedFileName(reactorArtifact, false)).exists());
+ FileUtils.deleteDirectory(mojo.outputDirectory);
+
+ mojo.excludeReactor = true;
+ mojo.execute();
+
+ for (Artifact artifact : artifacts) {
+ File file = new File(mojo.outputDirectory, DependencyUtil.getFormattedFileName(artifact, false));
+ assertEquals(artifact != reactorArtifact, file.exists(), artifact.getId());
+ }
+ }
+
@Test
@InjectMojo(goal = "copy-dependencies")
void testSubPerType(CopyDependenciesMojo mojo) throws Exception {