This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/maven-4.0.x by this push:
new 2e31220dc1 GH-11181 Metaversion validation and lax conflict detection
(#11184) (#11216)
2e31220dc1 is described below
commit 2e31220dc1d217ca8d8a4c0d7da8d56effd0702f
Author: Tamas Cservenak <[email protected]>
AuthorDate: Wed Oct 8 16:52:42 2025 +0200
GH-11181 Metaversion validation and lax conflict detection (#11184) (#11216)
Changes:
* validate for metaversions in extensions XML
* conflict detection should not report conflict for same V
* support for metaversions during extension resolution
Fixes #11181
Backport of 033bf6f9dfe710dbe4927cea7e3f57aa9b2f4b9b
---
.../org/apache/maven/cling/invoker/BaseParser.java | 47 ++++++---
.../invoker/PrecedenceCoreExtensionSelector.java | 3 +-
.../DefaultPluginDependenciesResolver.java | 33 +++++-
...venITgh11181CoreExtensionsMetaVersionsTest.java | 116 +++++++++++++++++++++
.../org/apache/maven/it/TestSuiteOrdering.java | 1 +
.../pw-metaversion-is-invalid/.mvn/extensions.xml | 8 ++
.../pw-metaversion-is-invalid/HOME/.placeholder | 0
.../pw-metaversion-is-invalid/pom.xml | 19 ++++
.../uw-metaversion-is-valid/.mvn/.placeholder | 0
.../HOME/.m2/extensions.xml | 8 ++
.../uw-metaversion-is-valid/pom.xml | 19 ++++
.../.mvn/extensions.xml | 8 ++
.../HOME/.m2/extensions.xml | 8 ++
.../uw-pw-different-version-is-conflict/pom.xml | 19 ++++
.../.mvn/extensions.xml | 8 ++
.../HOME/.m2/extensions.xml | 8 ++
.../uw-pw-same-version-is-not-conflict/pom.xml | 19 ++++
17 files changed, 306 insertions(+), 18 deletions(-)
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java
index c93150c61e..20247749e2 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java
@@ -489,21 +489,21 @@ protected List<CoreExtensions>
readCoreExtensionsDescriptor(LocalContext context
// project
file =
context.cwd.resolve(eff.get(Constants.MAVEN_PROJECT_EXTENSIONS));
- loaded = readCoreExtensionsDescriptorFromFile(file);
+ loaded = readCoreExtensionsDescriptorFromFile(file, false);
if (!loaded.isEmpty()) {
result.add(new CoreExtensions(file, loaded));
}
// user
file =
context.userHomeDirectory.resolve(eff.get(Constants.MAVEN_USER_EXTENSIONS));
- loaded = readCoreExtensionsDescriptorFromFile(file);
+ loaded = readCoreExtensionsDescriptorFromFile(file, true);
if (!loaded.isEmpty()) {
result.add(new CoreExtensions(file, loaded));
}
// installation
file =
context.installationDirectory.resolve(eff.get(Constants.MAVEN_INSTALLATION_EXTENSIONS));
- loaded = readCoreExtensionsDescriptorFromFile(file);
+ loaded = readCoreExtensionsDescriptorFromFile(file, true);
if (!loaded.isEmpty()) {
result.add(new CoreExtensions(file, loaded));
}
@@ -511,7 +511,7 @@ protected List<CoreExtensions>
readCoreExtensionsDescriptor(LocalContext context
return result.isEmpty() ? null : List.copyOf(result);
}
- protected List<CoreExtension> readCoreExtensionsDescriptorFromFile(Path
extensionsFile) {
+ protected List<CoreExtension> readCoreExtensionsDescriptorFromFile(Path
extensionsFile, boolean allowMetaVersions) {
try {
if (extensionsFile != null && Files.exists(extensionsFile)) {
try (InputStream is = Files.newInputStream(extensionsFile)) {
@@ -519,7 +519,8 @@ protected List<CoreExtension>
readCoreExtensionsDescriptorFromFile(Path extensio
extensionsFile,
List.copyOf(new CoreExtensionsStaxReader()
.read(is, true, new
InputSource(extensionsFile.toString()))
- .getExtensions()));
+ .getExtensions()),
+ allowMetaVersions);
}
}
return List.of();
@@ -529,23 +530,37 @@ protected List<CoreExtension>
readCoreExtensionsDescriptorFromFile(Path extensio
}
protected List<CoreExtension> validateCoreExtensionsDescriptorFromFile(
- Path extensionFile, List<CoreExtension> coreExtensions) {
+ Path extensionFile, List<CoreExtension> coreExtensions, boolean
allowMetaVersions) {
Map<String, List<InputLocation>> gasLocations = new HashMap<>();
+ Map<String, List<InputLocation>> metaVersionLocations = new
HashMap<>();
for (CoreExtension coreExtension : coreExtensions) {
String ga = coreExtension.getGroupId() + ":" +
coreExtension.getArtifactId();
InputLocation location = coreExtension.getLocation("");
gasLocations.computeIfAbsent(ga, k -> new
ArrayList<>()).add(location);
+ // TODO: metaversions could be extensible enum with these two
values out of the box
+ if ("LATEST".equals(coreExtension.getVersion()) ||
"RELEASE".equals(coreExtension.getVersion())) {
+ metaVersionLocations.computeIfAbsent(ga, k -> new
ArrayList<>()).add(location);
+ }
}
- if (gasLocations.values().stream().noneMatch(l -> l.size() > 1)) {
- return coreExtensions;
- }
- throw new IllegalStateException("Extension conflicts in file " +
extensionFile + ": "
- + gasLocations.entrySet().stream()
- .map(e -> e.getKey() + " defined on lines "
- + e.getValue().stream()
- .map(l ->
String.valueOf(l.getLineNumber()))
- .collect(Collectors.joining(", ")))
- .collect(Collectors.joining("; ")));
+ if (gasLocations.values().stream().anyMatch(l -> l.size() > 1)) {
+ throw new IllegalStateException("Extension conflicts in file " +
extensionFile + ": "
+ + gasLocations.entrySet().stream()
+ .map(e -> e.getKey() + " defined on lines "
+ + e.getValue().stream()
+ .map(l ->
String.valueOf(l.getLineNumber()))
+ .collect(Collectors.joining(", ")))
+ .collect(Collectors.joining("; ")));
+ }
+ if (!allowMetaVersions && !metaVersionLocations.isEmpty()) {
+ throw new IllegalStateException("Extension with illegal version in
file " + extensionFile + ": "
+ + metaVersionLocations.entrySet().stream()
+ .map(e -> e.getKey() + " defined on lines "
+ + e.getValue().stream()
+ .map(l ->
String.valueOf(l.getLineNumber()))
+ .collect(Collectors.joining(", ")))
+ .collect(Collectors.joining("; ")));
+ }
+ return coreExtensions;
}
@Nullable
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/PrecedenceCoreExtensionSelector.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/PrecedenceCoreExtensionSelector.java
index 6edfde98ee..590529d5f1 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/PrecedenceCoreExtensionSelector.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/PrecedenceCoreExtensionSelector.java
@@ -21,6 +21,7 @@
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
import org.apache.maven.api.cli.CoreExtensions;
@@ -60,7 +61,7 @@ protected List<CoreExtension> selectCoreExtensions(C context,
List<CoreExtension
for (CoreExtension coreExtension :
coreExtensions.coreExtensions()) {
String key = coreExtension.getGroupId() + ":" +
coreExtension.getArtifactId();
CoreExtension conflict = selectedExtensions.putIfAbsent(key,
coreExtension);
- if (conflict != null) {
+ if (conflict != null &&
!Objects.equals(coreExtension.getVersion(), conflict.getVersion())) {
conflicts.add(String.format(
"Conflicting extension %s: %s vs %s",
key,
diff --git
a/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
b/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
index f4e667ac64..fad79cc941 100644
---
a/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
+++
b/impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
@@ -159,7 +159,38 @@ public DependencyResult resolveCoreExtension(
List<RemoteRepository> repositories,
RepositorySystemSession session)
throws PluginResolutionException {
- return resolveInternal(plugin, null /* pluginArtifact */,
dependencyFilter, repositories, session);
+ RequestTrace trace = RequestTrace.newChild(null, plugin);
+
+ Artifact pluginArtifact = toArtifact(plugin, session);
+
+ try {
+ DefaultRepositorySystemSession pluginSession = new
DefaultRepositorySystemSession(session);
+ pluginSession.setArtifactDescriptorPolicy(new
SimpleArtifactDescriptorPolicy(true, false));
+
+ ArtifactDescriptorRequest request =
+ new ArtifactDescriptorRequest(pluginArtifact,
repositories, REPOSITORY_CONTEXT);
+ request.setTrace(trace);
+ ArtifactDescriptorResult result =
repoSystem.readArtifactDescriptor(pluginSession, request);
+
+ for (MavenPluginDependenciesValidator dependenciesValidator :
dependenciesValidators) {
+ dependenciesValidator.validate(session, pluginArtifact,
result);
+ }
+
+ pluginArtifact = result.getArtifact();
+
+ if (logger.isWarnEnabled() && !result.getRelocations().isEmpty()) {
+ String message =
+ pluginArtifact instanceof RelocatedArtifact relocated
? ": " + relocated.getMessage() : "";
+ logger.warn(
+ "The extension {} has been relocated to {}{}",
+ result.getRelocations().get(0),
+ pluginArtifact,
+ message);
+ }
+ return resolveInternal(plugin, pluginArtifact, dependencyFilter,
repositories, session);
+ } catch (ArtifactDescriptorException e) {
+ throw new PluginResolutionException(plugin,
e.getResult().getExceptions(), e);
+ }
}
@Override
diff --git
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11181CoreExtensionsMetaVersionsTest.java
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11181CoreExtensionsMetaVersionsTest.java
new file mode 100644
index 0000000000..93c33c9f29
--- /dev/null
+++
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11181CoreExtensionsMetaVersionsTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.it;
+
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * This is a test set for GH-11181.
+ */
+class MavenITgh11181CoreExtensionsMetaVersionsTest extends
AbstractMavenIntegrationTestCase {
+ MavenITgh11181CoreExtensionsMetaVersionsTest() {
+ super("[4.1.0-SNAPSHOT,)");
+ }
+
+ /**
+ * Project wide extensions: use of meta versions is invalid.
+ */
+ @Test
+ void pwMetaVersionIsInvalid() throws Exception {
+ Path testDir =
extractResources("/gh-11181-core-extensions-meta-versions")
+ .toPath()
+ .toAbsolutePath()
+ .resolve("pw-metaversion-is-invalid");
+ Verifier verifier = newVerifier(testDir.toString());
+ verifier.setUserHomeDirectory(testDir.resolve("HOME"));
+ verifier.setAutoclean(false);
+ verifier.addCliArgument("validate");
+ try {
+ verifier.execute();
+ fail("Expected VerificationException");
+ } catch (VerificationException e) {
+ // there is not even a log; this is very early failure
+ assertTrue(e.getMessage().contains("Error executing Maven."));
+ }
+ }
+
+ /**
+ * User wide extensions: use of meta versions is valid.
+ */
+ @Test
+ void uwMetaVersionIsValid() throws Exception {
+ Path testDir =
extractResources("/gh-11181-core-extensions-meta-versions")
+ .toPath()
+ .toAbsolutePath()
+ .resolve("uw-metaversion-is-valid");
+ Verifier verifier = newVerifier(testDir.toString());
+ verifier.setUserHomeDirectory(testDir.resolve("HOME"));
+ verifier.setHandleLocalRepoTail(false);
+ verifier.setAutoclean(false);
+ verifier.addCliArgument("validate");
+ verifier.execute();
+
+ verifier.verifyErrorFreeLog();
+ }
+
+ /**
+ * Same GA different V extensions in project-wide and user-wide: warn for
conflict.
+ */
+ @Test
+ void uwPwDifferentVersionIsConflict() throws Exception {
+ Path testDir =
extractResources("/gh-11181-core-extensions-meta-versions")
+ .toPath()
+ .toAbsolutePath()
+ .resolve("uw-pw-different-version-is-conflict");
+ Verifier verifier = newVerifier(testDir.toString());
+ verifier.setUserHomeDirectory(testDir.resolve("HOME"));
+ verifier.setHandleLocalRepoTail(false);
+ verifier.setAutoclean(false);
+ verifier.addCliArgument("validate");
+ verifier.execute();
+
+ verifier.verifyErrorFreeLog();
+ verifier.verifyTextInLog("WARNING");
+ verifier.verifyTextInLog("Conflicting extension
io.takari.maven:takari-smart-builder");
+ }
+
+ /**
+ * Same GAV extensions in project-wide and user-wide: do not warn for
conflict.
+ */
+ @Test
+ void uwPwSameVersionIsNotConflict() throws Exception {
+ Path testDir =
extractResources("/gh-11181-core-extensions-meta-versions")
+ .toPath()
+ .toAbsolutePath()
+ .resolve("uw-pw-same-version-is-not-conflict");
+ Verifier verifier = newVerifier(testDir.toString());
+ verifier.setUserHomeDirectory(testDir.resolve("HOME"));
+ verifier.setHandleLocalRepoTail(false);
+ verifier.setAutoclean(false);
+ verifier.addCliArgument("validate");
+ verifier.execute();
+
+ verifier.verifyErrorFreeLog();
+ verifier.verifyTextNotInLog("WARNING");
+ }
+}
diff --git
a/its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java
b/its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java
index 207595094a..a0988a2ae1 100644
--- a/its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java
+++ b/its/core-it-suite/src/test/java/org/apache/maven/it/TestSuiteOrdering.java
@@ -103,6 +103,7 @@ public TestSuiteOrdering() {
* the tests are to finishing. Newer tests are also more likely to
fail, so this is
* a fail fast technique as well.
*/
+ suite.addTestSuite(MavenITgh11181CoreExtensionsMetaVersionsTest.class);
suite.addTestSuite(MavenITgh11055DIServiceInjectionTest.class);
suite.addTestSuite(MavenITgh11084ReactorReaderPreferConsumerPomTest.class);
suite.addTestSuite(MavenITgh10210SettingsXmlDecryptTest.class);
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/pw-metaversion-is-invalid/.mvn/extensions.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/pw-metaversion-is-invalid/.mvn/extensions.xml
new file mode 100644
index 0000000000..aeb80a24e7
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/pw-metaversion-is-invalid/.mvn/extensions.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<extensions>
+ <extension>
+ <groupId>io.takari.maven</groupId>
+ <artifactId>takari-smart-builder</artifactId>
+ <version>RELEASE</version>
+ </extension>
+</extensions>
\ No newline at end of file
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/pw-metaversion-is-invalid/HOME/.placeholder
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/pw-metaversion-is-invalid/HOME/.placeholder
new file mode 100644
index 0000000000..e69de29bb2
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/pw-metaversion-is-invalid/pom.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/pw-metaversion-is-invalid/pom.xml
new file mode 100644
index 0000000000..c663f5ff86
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/pw-metaversion-is-invalid/pom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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.gh11181</groupId>
+ <artifactId>pw-metaversion-is-invalid</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>5.13.4</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-metaversion-is-valid/.mvn/.placeholder
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-metaversion-is-valid/.mvn/.placeholder
new file mode 100644
index 0000000000..e69de29bb2
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-metaversion-is-valid/HOME/.m2/extensions.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-metaversion-is-valid/HOME/.m2/extensions.xml
new file mode 100644
index 0000000000..aeb80a24e7
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-metaversion-is-valid/HOME/.m2/extensions.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<extensions>
+ <extension>
+ <groupId>io.takari.maven</groupId>
+ <artifactId>takari-smart-builder</artifactId>
+ <version>RELEASE</version>
+ </extension>
+</extensions>
\ No newline at end of file
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-metaversion-is-valid/pom.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-metaversion-is-valid/pom.xml
new file mode 100644
index 0000000000..f33d5f7ed8
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-metaversion-is-valid/pom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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.gh11181</groupId>
+ <artifactId>uw-metaversion-is-valid</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>5.13.4</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/.mvn/extensions.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/.mvn/extensions.xml
new file mode 100644
index 0000000000..efadc86545
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/.mvn/extensions.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<extensions>
+ <extension>
+ <groupId>io.takari.maven</groupId>
+ <artifactId>takari-smart-builder</artifactId>
+ <version>1.1.0</version>
+ </extension>
+</extensions>
\ No newline at end of file
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/HOME/.m2/extensions.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/HOME/.m2/extensions.xml
new file mode 100644
index 0000000000..abe8e2d3ae
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/HOME/.m2/extensions.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<extensions>
+ <extension>
+ <groupId>io.takari.maven</groupId>
+ <artifactId>takari-smart-builder</artifactId>
+ <version>1.0.2</version>
+ </extension>
+</extensions>
\ No newline at end of file
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/pom.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/pom.xml
new file mode 100644
index 0000000000..f33d5f7ed8
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-different-version-is-conflict/pom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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.gh11181</groupId>
+ <artifactId>uw-metaversion-is-valid</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>5.13.4</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/.mvn/extensions.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/.mvn/extensions.xml
new file mode 100644
index 0000000000..efadc86545
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/.mvn/extensions.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<extensions>
+ <extension>
+ <groupId>io.takari.maven</groupId>
+ <artifactId>takari-smart-builder</artifactId>
+ <version>1.1.0</version>
+ </extension>
+</extensions>
\ No newline at end of file
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/HOME/.m2/extensions.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/HOME/.m2/extensions.xml
new file mode 100644
index 0000000000..efadc86545
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/HOME/.m2/extensions.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<extensions>
+ <extension>
+ <groupId>io.takari.maven</groupId>
+ <artifactId>takari-smart-builder</artifactId>
+ <version>1.1.0</version>
+ </extension>
+</extensions>
\ No newline at end of file
diff --git
a/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/pom.xml
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/pom.xml
new file mode 100644
index 0000000000..f33d5f7ed8
--- /dev/null
+++
b/its/core-it-suite/src/test/resources/gh-11181-core-extensions-meta-versions/uw-pw-same-version-is-not-conflict/pom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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.gh11181</groupId>
+ <artifactId>uw-metaversion-is-valid</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>5.13.4</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>