From 4ac22a5e95479634d0b1fcb5456724744e25bd61 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Sat, 13 Dec 2025 15:21:41 +0100 Subject: [PATCH 1/7] Relax the restriction about the "group:artifact:version" coordinates that can be attached. Still require the group and version to be the same, but allow the artifact to differ. The intend is to support multi-module project where more than one artifact may be produced. --- .../internal/impl/DefaultProjectManager.java | 17 +++++++++-------- .../impl/DefaultProjectManagerTest.java | 11 ++++++++++- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index 7c495a7344bc..0844513b8bc5 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -119,15 +119,16 @@ public void attachArtifact(@Nonnull Project project, @Nonnull ProducedArtifact a artifact.getExtension(), null); } - if (!Objects.equals(project.getGroupId(), artifact.getGroupId()) - || !Objects.equals(project.getArtifactId(), artifact.getArtifactId()) - || !Objects.equals( - project.getVersion(), artifact.getBaseVersion().toString())) { + // Verify groupId and version, intentionally allow artifactId to differ as a project may be multi-module. + String g1 = project.getGroupId(); + String g2 = artifact.getGroupId(); + String v1 = project.getVersion(); + String v2 = artifact.getBaseVersion().toString(); + if (!Objects.equals(g1, g2) || !Objects.equals(v1, v2)) { throw new IllegalArgumentException( - "The produced artifact must have the same groupId/artifactId/version than the project it is attached to. Expecting " - + project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion() - + " but received " + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" - + artifact.getBaseVersion()); + "The produced artifact must have the same groupId and version than the project it is attached to. Expecting " + + g1 + ':' + project.getArtifactId() + ':' + v1 + " but received " + + g2 + ':' + artifact.getArtifactId() + ':' + v2); } getMavenProject(project) .addAttachedArtifact( diff --git a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java index 560fd9941b6b..6a9cf9efd225 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java @@ -32,6 +32,7 @@ import org.mockito.Mockito; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; class DefaultProjectManagerTest { @@ -56,7 +57,15 @@ void attachArtifact() { when(artifact.getBaseVersion()).thenReturn(versionParser.parseVersion("1.0-SNAPSHOT")); projectManager.attachArtifact(project, artifact, path); + // Verify that no exception is thrown when only the arficactId differ when(artifact.getArtifactId()).thenReturn("anotherArtifact"); - assertThrows(IllegalArgumentException.class, () -> projectManager.attachArtifact(project, artifact, path)); + projectManager.attachArtifact(project, artifact, path); + + when(artifact.getGroupId()).thenReturn("anotherGroup"); + String message = assertThrows( + IllegalArgumentException.class, () -> projectManager.attachArtifact(project, artifact, path)) + .getMessage(); + assertTrue(message.contains("myGroup:myArtifact:1.0-SNAPSHOT")); + assertTrue(message.contains("anotherGroup:anotherArtifact:1.0-SNAPSHOT")); } } From 55fe81f268902e4c116019f3e5c0660c3b37c2b1 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Sun, 14 Dec 2025 11:25:14 +0100 Subject: [PATCH 2/7] Fix a typo and add a comment in the test. --- .../apache/maven/internal/impl/DefaultProjectManagerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java index 6a9cf9efd225..dd82f9855593 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java @@ -57,10 +57,11 @@ void attachArtifact() { when(artifact.getBaseVersion()).thenReturn(versionParser.parseVersion("1.0-SNAPSHOT")); projectManager.attachArtifact(project, artifact, path); - // Verify that no exception is thrown when only the arficactId differ + // Verify that no exception is thrown when only the artifactId differs when(artifact.getArtifactId()).thenReturn("anotherArtifact"); projectManager.attachArtifact(project, artifact, path); + // Verify that an exception is thrown when the groupId differs when(artifact.getGroupId()).thenReturn("anotherGroup"); String message = assertThrows( IllegalArgumentException.class, () -> projectManager.attachArtifact(project, artifact, path)) From 5743e6ba5f84e54b57716d9c607c8ebe5f7f326b Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Sun, 14 Dec 2025 13:23:55 +0100 Subject: [PATCH 3/7] Fix English grammar reported during PR review. --- .../org/apache/maven/internal/impl/DefaultProjectManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index 0844513b8bc5..f124be348629 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -126,7 +126,7 @@ public void attachArtifact(@Nonnull Project project, @Nonnull ProducedArtifact a String v2 = artifact.getBaseVersion().toString(); if (!Objects.equals(g1, g2) || !Objects.equals(v1, v2)) { throw new IllegalArgumentException( - "The produced artifact must have the same groupId and version than the project it is attached to. Expecting " + "The produced artifact must have the same groupId and version as the project it is attached to. Expecting " + g1 + ':' + project.getArtifactId() + ':' + v1 + " but received " + g2 + ':' + artifact.getArtifactId() + ':' + v2); } From f2cf71f329523bc7daff33e3913094680725ac10 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Mon, 15 Dec 2025 14:51:37 +0100 Subject: [PATCH 4/7] If the `artifactId` is changed, accept only the ones that are the name of a Java module. --- .../internal/impl/DefaultProjectManager.java | 28 +++++++-- .../impl/DefaultProjectManagerTest.java | 63 +++++++++++++++---- .../apache/maven/impl/DefaultSourceRoot.java | 2 +- 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index f124be348629..14876ab397f9 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -121,14 +121,30 @@ public void attachArtifact(@Nonnull Project project, @Nonnull ProducedArtifact a } // Verify groupId and version, intentionally allow artifactId to differ as a project may be multi-module. String g1 = project.getGroupId(); - String g2 = artifact.getGroupId(); + String a1 = project.getArtifactId(); String v1 = project.getVersion(); + String g2 = artifact.getGroupId(); + String a2 = artifact.getArtifactId(); String v2 = artifact.getBaseVersion().toString(); - if (!Objects.equals(g1, g2) || !Objects.equals(v1, v2)) { - throw new IllegalArgumentException( - "The produced artifact must have the same groupId and version as the project it is attached to. Expecting " - + g1 + ':' + project.getArtifactId() + ':' + v1 + " but received " - + g2 + ':' + artifact.getArtifactId() + ':' + v2); + + // ArtifactId may differ only for multi-module projects (source roots with module name) + boolean isMultiModule = false; + boolean artifactMatchesModule = false; + for (SourceRoot sr : getSourceRoots(project)) { + Optional moduleName = sr.module(); + if (moduleName.isPresent()) { + isMultiModule = true; + if (moduleName.get().equals(a2)) { + artifactMatchesModule = true; + break; + } + } + } + if (!(Objects.equals(g1, g2) && Objects.equals(v1, v2) && (artifactMatchesModule || Objects.equals(a1, a2)))) { + throw new IllegalArgumentException(String.format( + "The produced artifact must have the same groupId%s and version as the project it is attached to.%n" + + "Expecting %s:%s:%s but received %s:%s:%s.", + isMultiModule ? "" : ", artifactID", g1, a1, v1, g2, a2, v2)); } getMavenProject(project) .addAttachedArtifact( diff --git a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java index dd82f9855593..ea18ef4f0670 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java @@ -20,11 +20,15 @@ import java.nio.file.Path; import java.nio.file.Paths; +import java.util.function.Supplier; +import org.apache.maven.api.Language; import org.apache.maven.api.ProducedArtifact; import org.apache.maven.api.Project; +import org.apache.maven.api.ProjectScope; import org.apache.maven.api.services.ArtifactManager; import org.apache.maven.impl.DefaultModelVersionParser; +import org.apache.maven.impl.DefaultSourceRoot; import org.apache.maven.impl.DefaultVersionParser; import org.apache.maven.project.MavenProject; import org.eclipse.aether.util.version.GenericVersionScheme; @@ -37,17 +41,25 @@ class DefaultProjectManagerTest { + private DefaultProjectManager projectManager; + + private Project project; + + private ProducedArtifact artifact; + + private Path artifactPath; + @Test void attachArtifact() { InternalMavenSession session = Mockito.mock(InternalMavenSession.class); ArtifactManager artifactManager = Mockito.mock(ArtifactManager.class); MavenProject mavenProject = new MavenProject(); - Project project = new DefaultProject(session, mavenProject); - ProducedArtifact artifact = Mockito.mock(ProducedArtifact.class); - Path path = Paths.get(""); + project = new DefaultProject(session, mavenProject); + artifact = Mockito.mock(ProducedArtifact.class); + artifactPath = Paths.get(""); DefaultVersionParser versionParser = new DefaultVersionParser(new DefaultModelVersionParser(new GenericVersionScheme())); - DefaultProjectManager projectManager = new DefaultProjectManager(session, artifactManager); + projectManager = new DefaultProjectManager(session, artifactManager); mavenProject.setGroupId("myGroup"); mavenProject.setArtifactId("myArtifact"); @@ -55,18 +67,47 @@ void attachArtifact() { when(artifact.getGroupId()).thenReturn("myGroup"); when(artifact.getArtifactId()).thenReturn("myArtifact"); when(artifact.getBaseVersion()).thenReturn(versionParser.parseVersion("1.0-SNAPSHOT")); - projectManager.attachArtifact(project, artifact, path); + projectManager.attachArtifact(project, artifact, artifactPath); - // Verify that no exception is thrown when only the artifactId differs + // Verify that an exception is thrown when the artifactId differs when(artifact.getArtifactId()).thenReturn("anotherArtifact"); - projectManager.attachArtifact(project, artifact, path); + assertExceptionMessageContains("myGroup:anotherArtifact:1.0-SNAPSHOT"); + + // Add a Java module. It should relax the restriction on artifactId. + projectManager.addSourceRoot( + project, + new DefaultSourceRoot( + ProjectScope.MAIN, + Language.JAVA_FAMILY, + "org.foo.bar", + null, + Path.of("myProject"), + null, + null, + false, + null, + true)); + + // Verify that we get the same exception when the artifactId does not match the module name + assertExceptionMessageContains("myGroup:anotherArtifact:1.0-SNAPSHOT"); + + // Verify that no exception is thrown when the artifactId is the module name + when(artifact.getArtifactId()).thenReturn("org.foo.bar"); + projectManager.attachArtifact(project, artifact, artifactPath); // Verify that an exception is thrown when the groupId differs when(artifact.getGroupId()).thenReturn("anotherGroup"); - String message = assertThrows( - IllegalArgumentException.class, () -> projectManager.attachArtifact(project, artifact, path)) + assertExceptionMessageContains("anotherGroup:org.foo.bar:1.0-SNAPSHOT"); + } + + private void assertExceptionMessageContains(String expectedGAV) { + String cause = assertThrows( + IllegalArgumentException.class, + () -> projectManager.attachArtifact(project, artifact, artifactPath)) .getMessage(); - assertTrue(message.contains("myGroup:myArtifact:1.0-SNAPSHOT")); - assertTrue(message.contains("anotherGroup:anotherArtifact:1.0-SNAPSHOT")); + Supplier message = () -> + String.format("The exception message does not contain the expected GAV. Message was:%n%s%n", cause); + assertTrue(cause.contains("myGroup:myArtifact:1.0-SNAPSHOT"), message); + assertTrue(cause.contains(expectedGAV), message); } } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java index 870b429517f4..d2b0142cfc4e 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java @@ -94,7 +94,7 @@ public DefaultSourceRoot( @Nonnull Language language, @Nullable String moduleName, @Nullable Version targetVersionOrNull, - @Nullable Path directory, + @Nonnull Path directory, @Nullable List includes, @Nullable List excludes, boolean stringFiltering, From e373de9a37c4d6742778863d893559b6714309dd Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Mon, 15 Dec 2025 15:43:33 +0100 Subject: [PATCH 5/7] Build the exception message separately for the modular and non-modular case. --- .../internal/impl/DefaultProjectManager.java | 28 ++++++++++++++----- .../impl/DefaultProjectManagerTest.java | 18 ++++++++---- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index 14876ab397f9..54ecb424f16f 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -129,22 +129,36 @@ public void attachArtifact(@Nonnull Project project, @Nonnull ProducedArtifact a // ArtifactId may differ only for multi-module projects (source roots with module name) boolean isMultiModule = false; - boolean artifactMatchesModule = false; + boolean validArtifactId = Objects.equals(a1, a2); for (SourceRoot sr : getSourceRoots(project)) { Optional moduleName = sr.module(); if (moduleName.isPresent()) { isMultiModule = true; if (moduleName.get().equals(a2)) { - artifactMatchesModule = true; + validArtifactId = true; break; } } } - if (!(Objects.equals(g1, g2) && Objects.equals(v1, v2) && (artifactMatchesModule || Objects.equals(a1, a2)))) { - throw new IllegalArgumentException(String.format( - "The produced artifact must have the same groupId%s and version as the project it is attached to.%n" - + "Expecting %s:%s:%s but received %s:%s:%s.", - isMultiModule ? "" : ", artifactID", g1, a1, v1, g2, a2, v2)); + boolean isSameGroupAndVersion = Objects.equals(g1, g2) && Objects.equals(v1, v2); + if (isMultiModule) { + if (!isSameGroupAndVersion) { + throw new IllegalArgumentException(String.format( + "The produced artifact must have the same groupId and version as the project it is attached to.%n" + + "Expecting \"%s:%s:%s\" but received \"%s:%s:%s\".", + g1, validArtifactId ? a2 : "${module}", v1, g2, a2, v2)); + } + if (!validArtifactId) { + throw new IllegalArgumentException(String.format( + "The produced artifactId must be the name of a Java module. It cannot be \"%s\".", a2)); + } + } else { + if (!(isSameGroupAndVersion && validArtifactId)) { + throw new IllegalArgumentException(String.format( + "The produced artifact must have the same groupId, artifactId and version as the project it is attached to.%n" + + "Expecting \"%s:%s:%s\" but received \"%s:%s:%s\".", + g1, a1, v1, g2, a2, v2)); + } } getMavenProject(project) .addAttachedArtifact( diff --git a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java index ea18ef4f0670..71f2b830c624 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java @@ -71,7 +71,7 @@ void attachArtifact() { // Verify that an exception is thrown when the artifactId differs when(artifact.getArtifactId()).thenReturn("anotherArtifact"); - assertExceptionMessageContains("myGroup:anotherArtifact:1.0-SNAPSHOT"); + assertExceptionMessageContains("myGroup:myArtifact:1.0-SNAPSHOT", "myGroup:anotherArtifact:1.0-SNAPSHOT"); // Add a Java module. It should relax the restriction on artifactId. projectManager.addSourceRoot( @@ -89,7 +89,7 @@ void attachArtifact() { true)); // Verify that we get the same exception when the artifactId does not match the module name - assertExceptionMessageContains("myGroup:anotherArtifact:1.0-SNAPSHOT"); + assertExceptionMessageContains("", "anotherArtifact"); // Verify that no exception is thrown when the artifactId is the module name when(artifact.getArtifactId()).thenReturn("org.foo.bar"); @@ -97,17 +97,25 @@ void attachArtifact() { // Verify that an exception is thrown when the groupId differs when(artifact.getGroupId()).thenReturn("anotherGroup"); - assertExceptionMessageContains("anotherGroup:org.foo.bar:1.0-SNAPSHOT"); + assertExceptionMessageContains("myGroup:org.foo.bar:1.0-SNAPSHOT", "anotherGroup:org.foo.bar:1.0-SNAPSHOT"); } - private void assertExceptionMessageContains(String expectedGAV) { + /** + * Verifies that {@code projectManager.attachArtifact(…)} throws an exception, + * and that the expecption message contains the expected and actual GAV. + * + * @param expectedGAV the actual GAV that the exception message should contain + * @param actualGAV the actual GAV that the exception message should contain + */ + private void assertExceptionMessageContains(String expectedGAV, String actualGAV) { String cause = assertThrows( IllegalArgumentException.class, () -> projectManager.attachArtifact(project, artifact, artifactPath)) .getMessage(); Supplier message = () -> String.format("The exception message does not contain the expected GAV. Message was:%n%s%n", cause); - assertTrue(cause.contains("myGroup:myArtifact:1.0-SNAPSHOT"), message); + assertTrue(cause.contains(expectedGAV), message); + assertTrue(cause.contains(actualGAV), message); } } From 5c81883d98a08331fc3791fbee59ac00ed8ec175 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Mon, 15 Dec 2025 15:57:21 +0100 Subject: [PATCH 6/7] Clarify the exception message as suggested in the pull request. --- .../internal/impl/DefaultProjectManager.java | 41 +++++++++++-------- .../impl/DefaultProjectManagerTest.java | 2 +- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index 54ecb424f16f..5d7dcbcde906 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -141,24 +141,31 @@ public void attachArtifact(@Nonnull Project project, @Nonnull ProducedArtifact a } } boolean isSameGroupAndVersion = Objects.equals(g1, g2) && Objects.equals(v1, v2); - if (isMultiModule) { - if (!isSameGroupAndVersion) { - throw new IllegalArgumentException(String.format( - "The produced artifact must have the same groupId and version as the project it is attached to.%n" - + "Expecting \"%s:%s:%s\" but received \"%s:%s:%s\".", - g1, validArtifactId ? a2 : "${module}", v1, g2, a2, v2)); - } - if (!validArtifactId) { - throw new IllegalArgumentException(String.format( - "The produced artifactId must be the name of a Java module. It cannot be \"%s\".", a2)); - } - } else { - if (!(isSameGroupAndVersion && validArtifactId)) { - throw new IllegalArgumentException(String.format( - "The produced artifact must have the same groupId, artifactId and version as the project it is attached to.%n" - + "Expecting \"%s:%s:%s\" but received \"%s:%s:%s\".", - g1, a1, v1, g2, a2, v2)); + if (!(isSameGroupAndVersion && validArtifactId)) { + String message; + if (isMultiModule) { + // Multi-module project: artifactId may match any declared module name + message = String.format( + "Cannot attach artifact to project: groupId and version must match the project, " + + "and artifactId must match either the project or a declared module name.%n" + + " Project coordinates: %s:%s:%s%n" + + " Artifact coordinates: %s:%s:%s%n", + g1, a1, v1, g2, a2, v2); + if (isSameGroupAndVersion) { + message += String.format( + " Hint: The artifactId '%s' does not match the project artifactId '%s' " + + "nor any declared module name in source roots.", + a2, a1); + } + } else { + // Non-modular project: artifactId must match exactly + message = String.format( + "Cannot attach artifact to project: groupId, artifactId and version must match the project.%n" + + " Project coordinates: %s:%s:%s%n" + + " Artifact coordinates: %s:%s:%s", + g1, a1, v1, g2, a2, v2); } + throw new IllegalArgumentException(message); } getMavenProject(project) .addAttachedArtifact( diff --git a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java index 71f2b830c624..48e87f7cda65 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultProjectManagerTest.java @@ -97,7 +97,7 @@ void attachArtifact() { // Verify that an exception is thrown when the groupId differs when(artifact.getGroupId()).thenReturn("anotherGroup"); - assertExceptionMessageContains("myGroup:org.foo.bar:1.0-SNAPSHOT", "anotherGroup:org.foo.bar:1.0-SNAPSHOT"); + assertExceptionMessageContains("myGroup:myArtifact:1.0-SNAPSHOT", "anotherGroup:org.foo.bar:1.0-SNAPSHOT"); } /** From 0a3f364867d124503992f8e7f6e3aa0d0be7bfd0 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 16 Dec 2025 11:15:36 +0100 Subject: [PATCH 7/7] Edited comment as suggested in pull request. --- .../apache/maven/internal/impl/DefaultProjectManager.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index 5d7dcbcde906..aae6429912f4 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -119,7 +119,8 @@ public void attachArtifact(@Nonnull Project project, @Nonnull ProducedArtifact a artifact.getExtension(), null); } - // Verify groupId and version, intentionally allow artifactId to differ as a project may be multi-module. + // Verify groupId and version, intentionally allow artifactId to differ as Maven project may be + // multi-module with modular sources structure that provide module names used as artifactIds. String g1 = project.getGroupId(); String a1 = project.getArtifactId(); String v1 = project.getVersion(); @@ -127,7 +128,8 @@ public void attachArtifact(@Nonnull Project project, @Nonnull ProducedArtifact a String a2 = artifact.getArtifactId(); String v2 = artifact.getBaseVersion().toString(); - // ArtifactId may differ only for multi-module projects (source roots with module name) + // ArtifactId may differ only for multi-module projects, in which case + // it must match the module name from a source root in modular sources. boolean isMultiModule = false; boolean validArtifactId = Objects.equals(a1, a2); for (SourceRoot sr : getSourceRoots(project)) {