diff --git a/src/it/dependency-filesets-resources-test/invoker.properties b/src/it/dependency-filesets-resources-test/invoker.properties
new file mode 100644
index 0000000..f7d698e
--- /dev/null
+++ b/src/it/dependency-filesets-resources-test/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 generate-resources
diff --git a/src/it/dependency-filesets-resources-test/pom.xml b/src/it/dependency-filesets-resources-test/pom.xml
new file mode 100644
index 0000000..8c47b62
--- /dev/null
+++ b/src/it/dependency-filesets-resources-test/pom.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+ 4.0.0
+
+ org.apache.maven.plugins.antrun
+ dependency-filesets-resources-test
+ 1.0-SNAPSHOT
+ Test for the dependency resources reference of the dependencyfilesets task
+ Test for the dependency resources reference of the dependencyfilesets task
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ @pom.version@
+
+
+ antrun
+ generate-resources
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ @version.maven-clean-plugin@
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ @version.maven-site-plugin@
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ @version.maven-resources-plugin@
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ @version.maven-compiler-plugin@
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ @version.maven-surefire@
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ @version.maven-jar-plugin@
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+ @version.maven-install-plugin@
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ @version.maven-deploy-plugin@
+
+
+
+
+
+
+
+ org.apache.ant
+ ant
+ @version.ant@
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ @versions.junit5@
+
+
+
+
+
diff --git a/src/it/dependency-filesets-resources-test/src/main/java/Test.java b/src/it/dependency-filesets-resources-test/src/main/java/Test.java
new file mode 100644
index 0000000..7b5b646
--- /dev/null
+++ b/src/it/dependency-filesets-resources-test/src/main/java/Test.java
@@ -0,0 +1,29 @@
+
+/*
+ * 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.
+ */
+
+public class Test
+{
+
+ public static void main( String args[] )
+ {
+ System.out.println( "done" );
+ }
+
+}
diff --git a/src/it/dependency-filesets-resources-test/verify.bsh b/src/it/dependency-filesets-resources-test/verify.bsh
new file mode 100644
index 0000000..6d2a05f
--- /dev/null
+++ b/src/it/dependency-filesets-resources-test/verify.bsh
@@ -0,0 +1,50 @@
+
+/*
+ * 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.*;
+import java.util.*;
+import java.util.regex.*;
+
+import org.codehaus.plexus.util.*;
+
+try
+{
+ File depsDir = new File( basedir, "target/dependencies" );
+ File antJar = new File( depsDir, "ant-" + scriptVarVersionAnt + ".jar" );
+ File junitJar = new File( depsDir, "junit-jupiter-engine-" + scriptVarVersionJunit + ".jar" );
+
+ if ( ! antJar.exists() || antJar.isDirectory() )
+ {
+ System.out.println( "Ant jar file does not exist: " + antJar );
+ return false;
+ }
+ if ( ! junitJar.exists() || junitJar.isDirectory() )
+ {
+ System.out.println( "Junit jar file does not exist: " + junitJar );
+ return false;
+ }
+}
+catch( Throwable t )
+{
+ t.printStackTrace();
+ return false;
+}
+
+return true;
diff --git a/src/main/java/org/apache/maven/ant/tasks/DependencyFilesetsTask.java b/src/main/java/org/apache/maven/ant/tasks/DependencyFilesetsTask.java
index 818f506..ef168c5 100644
--- a/src/main/java/org/apache/maven/ant/tasks/DependencyFilesetsTask.java
+++ b/src/main/java/org/apache/maven/ant/tasks/DependencyFilesetsTask.java
@@ -33,6 +33,7 @@
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.resources.Union;
/**
* Ant task which create a fileset for each dependency in a Maven project, and a
@@ -72,6 +73,9 @@ public void execute() {
dependenciesFileSet.createExclude().setName("**");
}
+ Union dependenciesResourcesFileSet = new Union();
+ dependenciesResourcesFileSet.setProject(getProject());
+
for (Artifact artifact : depArtifacts) {
String relativeArtifactPath = localRepository.pathOf(artifact);
dependenciesFileSet.createInclude().setName(relativeArtifactPath);
@@ -81,10 +85,12 @@ public void execute() {
FileSet singleArtifactFileSet = new FileSet();
singleArtifactFileSet.setProject(getProject());
singleArtifactFileSet.setFile(artifact.getFile());
+ dependenciesResourcesFileSet.add(singleArtifactFileSet);
getProject().addReference(fileSetName, singleArtifactFileSet);
}
getProject().addReference((getPrefix() + getProjectDependenciesId()), dependenciesFileSet);
+ getProject().addReference((getPrefix() + getProjectDependenciesResourcesId()), dependenciesResourcesFileSet);
}
/**
@@ -162,6 +168,21 @@ public void setProjectDependenciesId(String projectDependenciesId) {
this.configuration.setProjectDependenciesId(projectDependenciesId);
}
+ /**
+ * @return RefId for the resource collection containing all project dependencies - default
+ * maven.project.dependencies.resources
+ */
+ public String getProjectDependenciesResourcesId() {
+ return this.configuration.getProjectDependenciesResourcesId();
+ }
+
+ /**
+ * @param projectDependenciesResourcesId RefId for the resource collection containing all project dependencies
+ */
+ public void setProjectDependenciesResourcesId(String projectDependenciesResourcesId) {
+ this.configuration.setProjectDependenciesResourcesId(projectDependenciesResourcesId);
+ }
+
/**
* Filter a set of artifacts using the scopes and type filters.
*
diff --git a/src/main/mdo/antrun.mdo b/src/main/mdo/antrun.mdo
index 4eb29c9..8e1b3a3 100644
--- a/src/main/mdo/antrun.mdo
+++ b/src/main/mdo/antrun.mdo
@@ -88,6 +88,13 @@ under the License.
maven.project.dependencies
RefId for the fileset containing all project dependencies
+
+ projectDependenciesResourcesId
+ String
+ maven.project.dependencies.resources
+ RefId for the resource collection containing all project dependencies, resolved from the actual
+ artifact files
+
scopes
String
diff --git a/src/test/java/org/apache/maven/ant/tasks/DependencyFilesetsTaskAggregateTest.java b/src/test/java/org/apache/maven/ant/tasks/DependencyFilesetsTaskAggregateTest.java
new file mode 100644
index 0000000..44640d8
--- /dev/null
+++ b/src/test/java/org/apache/maven/ant/tasks/DependencyFilesetsTaskAggregateTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.ant.tasks;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugins.antrun.AntRunMojo;
+import org.apache.maven.project.MavenProject;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.not;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test class for the aggregate dependency references of {@link DependencyFilesetsTask}.
+ */
+class DependencyFilesetsTaskAggregateTest {
+
+ private static final String LOCAL_REPOSITORY_REFID = "maven.local.repository";
+
+ private static final String LEGACY_DEPENDENCIES_REFID = "maven.project.dependencies";
+
+ private static final String DEPENDENCIES_RESOURCES_REFID = "maven.project.dependencies.resources";
+
+ @TempDir
+ Path folder;
+
+ /**
+ * The {@code maven.project.dependencies.resources} resource collection must be assembled from the actual resolved
+ * artifact files, so that artifacts located outside the local repository (e.g. reactor inter-module dependencies)
+ * are not silently omitted.
+ *
+ * @throws IOException In case of problems
+ */
+ @Test
+ void resourcesReferenceIncludesArtifactsOutsideLocalRepository() throws IOException {
+ Artifact localArtifact = newArtifact("org.example", "artX");
+ Artifact reactorArtifact = newArtifact("com.example", "artY");
+ DependencyFilesetsTask task = executeTask(localArtifact, reactorArtifact);
+
+ task.execute();
+
+ ResourceCollection resources =
+ (ResourceCollection) task.getProject().getReference(DEPENDENCIES_RESOURCES_REFID);
+ Set files = filesOf(resources);
+ assertThat(files, hasItem(localArtifact.getFile()));
+ assertThat(files, hasItem(reactorArtifact.getFile()));
+ }
+
+ /**
+ * The legacy {@code maven.project.dependencies} reference is preserved as a fileset rooted at the local
+ * repository, so it only contains artifacts physically present there.
+ *
+ * @throws IOException In case of problems
+ */
+ @Test
+ void legacyFilesetReferenceRemainsRootedAtLocalRepository() throws IOException {
+ Artifact localArtifact = newArtifact("org.example", "artX");
+ Artifact reactorArtifact = newArtifact("com.example", "artY");
+ DependencyFilesetsTask task = executeTask(localArtifact, reactorArtifact);
+
+ task.execute();
+
+ Object reference = task.getProject().getReference(LEGACY_DEPENDENCIES_REFID);
+ assertTrue(reference instanceof FileSet);
+ Set files = filesOf((ResourceCollection) reference);
+ assertThat(files, hasItem(localArtifact.getFile()));
+ assertThat(files, not(hasItem(reactorArtifact.getFile())));
+ }
+
+ private DependencyFilesetsTask executeTask(Artifact localArtifact, Artifact reactorArtifact) throws IOException {
+ Path localRepositoryDir = Files.createDirectories(folder.resolve("local-repository"));
+ Path reactorDirectory = Files.createDirectories(folder.resolve("reactor-module"));
+
+ File localArtifactFile =
+ localRepositoryDir.resolve(artifactPath(localArtifact)).toFile();
+ Files.createDirectories(localArtifactFile.getParentFile().toPath());
+ Files.write(localArtifactFile.toPath(), new byte[0]);
+ localArtifact.setFile(localArtifactFile);
+
+ File reactorArtifactFile = reactorDirectory.resolve("artY-1.0.jar").toFile();
+ Files.write(reactorArtifactFile.toPath(), new byte[0]);
+ reactorArtifact.setFile(reactorArtifactFile);
+
+ MavenProject mavenProject = new MavenProject();
+ Set artifacts = new HashSet<>();
+ artifacts.add(localArtifact);
+ artifacts.add(reactorArtifact);
+ mavenProject.setArtifacts(artifacts);
+
+ Project antProject = new Project();
+ antProject.addReference(AntRunMojo.DEFAULT_MAVEN_PROJECT_REFID, mavenProject);
+ antProject.addReference(LOCAL_REPOSITORY_REFID, newRepositoryStub(localRepositoryDir));
+
+ DependencyFilesetsTask task = new DependencyFilesetsTask();
+ task.setProject(antProject);
+ return task;
+ }
+
+ private Set filesOf(ResourceCollection resources) {
+ Set files = new HashSet<>();
+ for (Resource resource : resources) {
+ files.add(((FileResource) resource).getFile());
+ }
+ return files;
+ }
+
+ private Artifact newArtifact(String groupId, String artifactId) throws IOException {
+ Artifact artifact = new DefaultArtifact(
+ groupId, artifactId, "1.0", Artifact.SCOPE_COMPILE, "jar", null, new DefaultArtifactHandler("jar"));
+ artifact.setFile(Files.createTempFile(folder, artifactId, ".jar").toFile());
+ return artifact;
+ }
+
+ private ArtifactRepository newRepositoryStub(Path basedir) {
+ InvocationHandler handler = (proxy, method, args) -> {
+ switch (method.getName()) {
+ case "pathOf":
+ return artifactPath((Artifact) args[0]);
+ case "getBasedir":
+ return basedir.toString();
+ default:
+ return null;
+ }
+ };
+ return (ArtifactRepository)
+ Proxy.newProxyInstance(getClass().getClassLoader(), new Class>[] {ArtifactRepository.class}, handler);
+ }
+
+ private static String artifactPath(Artifact artifact) {
+ return artifact.getGroupId() + "/" + artifact.getArtifactId() + "/" + artifact.getVersion() + "/"
+ + artifact.getArtifactId() + "-" + artifact.getVersion() + "." + artifact.getType();
+ }
+}