diff --git a/src/it/projects/copy-dependencies-with-conflict/invoker.properties b/src/it/projects/copy-dependencies-with-conflict/invoker.properties
index f50e476fd..1b8f29fae 100644
--- a/src/it/projects/copy-dependencies-with-conflict/invoker.properties
+++ b/src/it/projects/copy-dependencies-with-conflict/invoker.properties
@@ -16,3 +16,4 @@
# under the License.
invoker.goals = clean process-sources
+invoker.buildResult = failure
diff --git a/src/it/projects/copy-dependencies-with-conflict/verify.groovy b/src/it/projects/copy-dependencies-with-conflict/verify.groovy
index 5405439d7..5a5234a37 100644
--- a/src/it/projects/copy-dependencies-with-conflict/verify.groovy
+++ b/src/it/projects/copy-dependencies-with-conflict/verify.groovy
@@ -21,11 +21,11 @@ File file = new File( basedir, "build.log" )
assert file.exists()
String buildLog = file.getText( "UTF-8" )
-assert buildLog.contains( '[WARNING] Overwriting ' )
-assert buildLog.contains( '[DEBUG] Copying artifact \'org.apache.maven.its.dependency.a:conflict:jar:1.0\'' )
-assert buildLog.contains( '[DEBUG] Copying artifact \'org.apache.maven.its.dependency.a:conflict:pom:1.0\'' )
-assert buildLog.contains( '[DEBUG] Copying artifact \'org.apache.maven.its.dependency.a:conflict:jar:1.0\'' )
-assert buildLog.contains( '[DEBUG] Copying artifact \'org.apache.maven.its.dependency.b:conflict:jar:1.0\'' )
-assert buildLog.contains( '[WARNING] Multiple files with the name conflict-1.0.jar in the dependency tree.' )
+assert buildLog.contains( 'Multiple artifacts map to the same destination file' )
+assert buildLog.contains( 'org.apache.maven.its.dependency.a:conflict' )
+assert buildLog.contains( 'org.apache.maven.its.dependency.b:conflict' )
+
+File copiedFile = new File( basedir, 'target/it/copy-dep-test-2/conflict-1.0.jar' )
+assert !copiedFile.exists()
return true
diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java
index 162914fd9..0b612da31 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java
@@ -54,8 +54,7 @@
/**
* Goal that copies the files for a project's dependencies from the repository to a directory.
* The default location to copy to is target/dependencies.
- * Since all files are copied to the same directory by default, a dependency that
- * has the same file name as another dependency will be overwritten.
+ * If dependencies map to the same destination file, the goal fails before copying to avoid overwriting an artifact.
*
* @author Brian Fox
* @since 1.0
@@ -161,18 +160,29 @@ protected void doExecute() throws MojoExecutionException {
Set artifacts = dss.getResolvedDependencies();
if (!useRepositoryLayout) {
- Map copies = new HashMap<>();
+ Map copies = new HashMap<>();
for (Artifact artifactItem : artifacts) {
String destFileName = DependencyUtil.getFormattedFileName(
artifactItem, stripVersion, prependGroupId, useBaseVersion, stripClassifier);
- int numCopies = copies.getOrDefault(destFileName, 0);
- copies.put(destFileName, numCopies + 1);
- }
- for (Map.Entry entry : copies.entrySet()) {
- if (entry.getValue() > 1) {
- getLog().warn("Multiple files with the name " + entry.getKey() + " in the dependency tree.");
- getLog().warn(
- "Not all JARs will be available. Consider using prependGroupId, useSubDirectoryPerArtifact, or useRepositoryLayout.");
+ File destDir = DependencyUtil.getFormattedOutputDirectory(
+ useSubDirectoryPerScope,
+ useSubDirectoryPerType,
+ useSubDirectoryPerArtifact,
+ useRepositoryLayout,
+ stripVersion,
+ stripType,
+ outputDirectory,
+ artifactItem);
+ File destFile = new File(destDir, destFileName)
+ .getAbsoluteFile()
+ .toPath()
+ .normalize()
+ .toFile();
+ Artifact existingArtifact = copies.putIfAbsent(destFile, artifactItem);
+ if (existingArtifact != null) {
+ throw new MojoExecutionException("Multiple artifacts map to the same destination file '" + destFile
+ + "': " + existingArtifact.getId() + " and " + artifactItem.getId()
+ + ". Consider using prependGroupId, useSubDirectoryPerArtifact, or useRepositoryLayout.");
}
}