diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SuperPomProvider.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SuperPomProvider.java index c413dfcf1ba..8b94ab83898 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SuperPomProvider.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SuperPomProvider.java @@ -20,6 +20,7 @@ import org.apache.maven.api.Service; import org.apache.maven.api.annotations.Experimental; +import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.model.Model; /** @@ -33,7 +34,8 @@ public interface SuperPomProvider extends Service { * * @param version The model version to retrieve the super POM for (e.g. "4.0.0"), must not be {@code null}. * @return The super POM, never {@code null}. - * @throws IllegalStateException if the super POM could not be retrieved + * @throws SuperPomProviderException if the super POM could not be retrieved */ - Model getSuperPom(String version); + @Nonnull + Model getSuperPom(@Nonnull String version); } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SuperPomProviderException.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SuperPomProviderException.java new file mode 100644 index 00000000000..4aa6890ca37 --- /dev/null +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SuperPomProviderException.java @@ -0,0 +1,43 @@ +/* + * 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.api.services; + +/** + * Exceptions thrown by the {@link SuperPomProvider} service. + * + * @since 4.0.0 + */ +public class SuperPomProviderException extends MavenException { + + public SuperPomProviderException() { + super(); + } + + public SuperPomProviderException(String message) { + super(message); + } + + public SuperPomProviderException(String message, Throwable cause) { + super(message, cause); + } + + public SuperPomProviderException(Throwable cause) { + super(cause); + } +} diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 18f0dea4d3a..946c903bdd7 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -29,6 +29,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -495,9 +496,12 @@ private void validatePrerequisitesForNonMavenPluginProjects(List p * @return A {@link Set} of profile identifiers, never {@code null}. */ private Set getAllProfiles(MavenSession session) { - final Model superPomModel = superPomProvider.getSuperModel("4.0.0").getDelegate(); + final Map superPomModels = new HashMap<>(); final Set projectsIncludingParents = new HashSet<>(); for (MavenProject project : session.getProjects()) { + superPomModels.computeIfAbsent( + project.getModelVersion(), + v -> superPomProvider.getSuperModel(v).getDelegate()); boolean isAdded = projectsIncludingParents.add(project); MavenProject parent = project.getParent(); while (isAdded && parent != null) { @@ -511,8 +515,9 @@ private Set getAllProfiles(MavenSession session) { .map(Profile::getId); final Stream settingsProfiles = session.getSettings().getProfiles().stream().map(org.apache.maven.settings.Profile::getId); - final Stream superPomProfiles = - superPomModel.getProfiles().stream().map(Profile::getId); + final Stream superPomProfiles = superPomModels.values().stream() + .flatMap(p -> p.getProfiles().stream()) + .map(Profile::getId); return Stream.of(projectProfiles, settingsProfiles, superPomProfiles) .flatMap(Function.identity()) diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSuperPomProvider.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSuperPomProvider.java index 2615dc5ab1d..51fd3a4817e 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSuperPomProvider.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSuperPomProvider.java @@ -24,6 +24,7 @@ import org.apache.maven.api.model.Model; import org.apache.maven.api.services.SuperPomProvider; +import org.apache.maven.api.services.SuperPomProviderException; @Named @Singleton @@ -38,6 +39,10 @@ public DefaultSuperPomProvider(org.apache.maven.model.superpom.SuperPomProvider @Override public Model getSuperPom(String version) { - return provider.getSuperModel(version).getDelegate(); + try { + return provider.getSuperModel(version).getDelegate(); + } catch (IllegalStateException e) { + throw new SuperPomProviderException("Could not retrieve super pom " + version, e); + } } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java index 3f6265736ec..ffde12ea9e6 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java @@ -746,7 +746,8 @@ private Model readEffectiveModel( problems.setRootModel(inputModel); ModelData resultData = new ModelData(request.getModelSource(), inputModel); - ModelData superData = new ModelData(null, getSuperModel()); + String superModelVersion = inputModel.getModelVersion() != null ? inputModel.getModelVersion() : "4.0.0"; + ModelData superData = new ModelData(null, getSuperModel(superModelVersion)); // profile activation DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request); @@ -1605,8 +1606,8 @@ private ModelData readParentExternally( modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); } - private Model getSuperModel() { - return superPomProvider.getSuperModel("4.0.0"); + private Model getSuperModel(String modelVersion) { + return superPomProvider.getSuperModel(modelVersion); } private void importDependencyManagement( diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java b/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java index 32b2efc1654..d7180c938a7 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java @@ -26,6 +26,8 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.api.model.InputSource; import org.apache.maven.model.Model; @@ -44,7 +46,7 @@ public class DefaultSuperPomProvider implements SuperPomProvider { /** * The cached super POM, lazily created. */ - private Model superModel; + private static final Map SUPER_MODELS = new ConcurrentHashMap<>(); @Inject public DefaultSuperPomProvider(ModelProcessor modelProcessor) { @@ -53,8 +55,8 @@ public DefaultSuperPomProvider(ModelProcessor modelProcessor) { @Override public Model getSuperModel(String version) { - if (superModel == null) { - String resource = "/org/apache/maven/model/pom-" + version + ".xml"; + return SUPER_MODELS.computeIfAbsent(Objects.requireNonNull(version), v -> { + String resource = "/org/apache/maven/model/pom-" + v + ".xml"; InputStream is = getClass().getResourceAsStream(resource); @@ -65,23 +67,21 @@ public Model getSuperModel(String version) { try { Map options = new HashMap<>(2); - options.put("xml:4.0.0", "xml:4.0.0"); + options.put("xml:" + version, "xml:" + version); - String modelId = "org.apache.maven:maven-model-builder:" + String modelId = "org.apache.maven:maven-model-builder:" + version + "-" + this.getClass().getPackage().getImplementationVersion() + ":super-pom"; InputSource inputSource = new InputSource( modelId, getClass().getResource(resource).toExternalForm()); options.put(ModelProcessor.INPUT_SOURCE, new org.apache.maven.model.InputSource(inputSource)); - superModel = modelProcessor.read(is, options); + return modelProcessor.read(is, options); } catch (IOException e) { throw new IllegalStateException( "The super POM " + resource + " is damaged" + ", please verify the integrity of your Maven installation", e); } - } - - return superModel; + }); } } diff --git a/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.1.0.xml b/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.1.0.xml new file mode 100644 index 00000000000..85f8334754a --- /dev/null +++ b/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.1.0.xml @@ -0,0 +1,64 @@ + + + + + + + 4.0.0 + + + UTF-8 + UTF-8 + + + + ${project.basedir}/target + ${project.build.directory}/classes + ${project.artifactId}-${project.version} + ${project.build.directory}/test-classes + ${project.basedir}/src/main/java + ${project.basedir}/src/main/scripts + ${project.basedir}/src/test/java + + + ${project.basedir}/src/main/resources + + + ${project.basedir}/src/main/resources-filtered + true + + + + + ${project.basedir}/src/test/resources + + + ${project.basedir}/src/test/resources-filtered + true + + + + + + ${project.build.directory}/site + + + +