diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java index 4a995e241dde..14141a6d0c6c 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ModelBuilderRequest.java @@ -59,7 +59,7 @@ enum RequestType { BUILD_EFFECTIVE, /** * The request is used specifically to parse the POM used as a basis for creating the consumer POM. - * This POM will not ungergo any profile activation. + * This POM will not undergo any profile activation. */ BUILD_CONSUMER, /** diff --git a/impl/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/impl/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 8735d1deab6b..debd7dbfc8b9 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/impl/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -111,6 +111,11 @@ public File findArtifact(Artifact artifact) { // No project, but most certainly a dependency which has been built previously File packagedArtifactFile = findInProjectLocalRepository(artifact); if (packagedArtifactFile != null && packagedArtifactFile.exists()) { + // Check if artifact is up-to-date + project = getProject(artifact, getAllProjects()); + if (project != null) { + isPackagedArtifactUpToDate(project, packagedArtifactFile); + } return packagedArtifactFile; } @@ -471,8 +476,11 @@ private Path getProjectLocalRepo() { } private MavenProject getProject(Artifact artifact) { - return getAllProjects() - .getOrDefault(artifact.getGroupId(), Collections.emptyMap()) + return getProject(artifact, getProjects()); + } + + private MavenProject getProject(Artifact artifact, Map>> projects) { + return projects.getOrDefault(artifact.getGroupId(), Collections.emptyMap()) .getOrDefault(artifact.getArtifactId(), Collections.emptyMap()) .getOrDefault(artifact.getBaseVersion(), null); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java index ba4b992b17af..0ad679efafdc 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java +++ b/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java @@ -145,7 +145,7 @@ public DefaultProjectBuilder( public ProjectBuildingResult build(File pomFile, ProjectBuildingRequest request) throws ProjectBuildingException { try (BuildSession bs = new BuildSession(request)) { Path path = pomFile.toPath(); - return bs.build(path, Sources.buildSource(path)); + return bs.build(false, path, Sources.buildSource(path)); } } @@ -170,7 +170,7 @@ static ModelSource toSource(org.apache.maven.model.building.ModelSource modelSou public ProjectBuildingResult build(ModelSource modelSource, ProjectBuildingRequest request) throws ProjectBuildingException { try (BuildSession bs = new BuildSession(request)) { - return bs.build(null, modelSource); + return bs.build(false, null, modelSource); } } @@ -184,7 +184,7 @@ public ProjectBuildingResult build(Artifact artifact, ProjectBuildingRequest req public ProjectBuildingResult build(Artifact artifact, boolean allowStubModel, ProjectBuildingRequest request) throws ProjectBuildingException { try (BuildSession bs = new BuildSession(request)) { - return bs.build(artifact, allowStubModel); + return bs.build(false, artifact, allowStubModel); } } @@ -342,7 +342,8 @@ class BuildSession implements AutoCloseable { @Override public void close() {} - ProjectBuildingResult build(Path pomFile, ModelSource modelSource) throws ProjectBuildingException { + ProjectBuildingResult build(boolean parent, Path pomFile, ModelSource modelSource) + throws ProjectBuildingException { ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader(); try { @@ -355,12 +356,27 @@ ProjectBuildingResult build(Path pomFile, ModelSource modelSource) throws Projec project = new MavenProject(); project.setFile(pomFile != null ? pomFile.toFile() : null); + boolean reactorMember = pomFile != null + && session.getProjects() != null // this is for UTs + && session.getProjects().stream() + .anyMatch( + p -> p.getPomPath().toAbsolutePath().equals(pomFile.toAbsolutePath())); + boolean isStandalone = pomFile == null + && modelSource != null + && modelSource.getLocation().startsWith("jar:") + && modelSource.getLocation().endsWith("/org/apache/maven/project/standalone.xml"); + ModelBuilderRequest.ModelBuilderRequestBuilder builder = getModelBuildingRequest(); - ModelBuilderRequest.RequestType type = pomFile != null - && this.request.isProcessPlugins() - && this.request.getValidationLevel() == ModelBuildingRequest.VALIDATION_LEVEL_STRICT + ModelBuilderRequest.RequestType type = reactorMember + || isStandalone + || (pomFile != null + && this.request.isProcessPlugins() + && this.request.getValidationLevel() + == ModelBuildingRequest.VALIDATION_LEVEL_STRICT) ? ModelBuilderRequest.RequestType.BUILD_EFFECTIVE - : ModelBuilderRequest.RequestType.CONSUMER_PARENT; + : (parent + ? ModelBuilderRequest.RequestType.CONSUMER_PARENT + : ModelBuilderRequest.RequestType.CONSUMER_DEPENDENCY); MavenProject theProject = project; ModelBuilderRequest request = builder.source(modelSource) .requestType(type) @@ -413,7 +429,8 @@ ProjectBuildingResult build(Path pomFile, ModelSource modelSource) throws Projec } } - ProjectBuildingResult build(Artifact artifact, boolean allowStubModel) throws ProjectBuildingException { + ProjectBuildingResult build(boolean parent, Artifact artifact, boolean allowStubModel) + throws ProjectBuildingException { org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact(artifact); pomArtifact = ArtifactDescriptorUtils.toPomArtifact(pomArtifact); @@ -437,7 +454,7 @@ ProjectBuildingResult build(Artifact artifact, boolean allowStubModel) throws Pr localProject = resItem.getRepository() instanceof org.apache.maven.api.WorkspaceRepository; } catch (ArtifactResolverException e) { if (e.getResult().getResults().values().iterator().next().isMissing() && allowStubModel) { - return build(null, createStubModelSource(artifact)); + return build(parent, null, createStubModelSource(artifact)); } throw new ProjectBuildingException( artifact.getId(), "Error resolving project artifact: " + e.getMessage(), e); @@ -452,9 +469,10 @@ ProjectBuildingResult build(Artifact artifact, boolean allowStubModel) throws Pr } if (localProject) { - return build(pomFile, Sources.buildSource(pomFile)); + return build(parent, pomFile, Sources.buildSource(pomFile)); } else { return build( + parent, null, Sources.resolvedSource( pomFile, @@ -791,6 +809,24 @@ private void initProject(MavenProject project, ModelBuilderResult result) { "Failed to create snapshot distribution repository for " + project.getId(), e); } } + + // remote repositories + List remoteRepositories = request.getRemoteRepositories(); + try { + remoteRepositories = projectBuildingHelper.createArtifactRepositories( + project.getModel().getRepositories(), remoteRepositories, request); + } catch (Exception e) { + result.getProblemCollector() + .reportProblem(new org.apache.maven.impl.model.DefaultModelProblem( + "", + Severity.ERROR, + Version.BASE, + project.getModel().getDelegate(), + -1, + -1, + e)); + } + project.setRemoteArtifactRepositories(remoteRepositories); } private void initParent(MavenProject project, ModelBuilderResult result) { @@ -810,12 +846,12 @@ private void initParent(MavenProject project, ModelBuilderResult result) { // remote repositories with those found in the pom.xml, along with the existing externally // defined repositories. // - request.setRemoteRepositories(project.getRemoteArtifactRepositories()); + request.getRemoteRepositories().addAll(project.getRemoteArtifactRepositories()); Path parentPomFile = parentModel.getPomFile(); if (parentPomFile != null) { project.setParentFile(parentPomFile.toFile()); try { - parent = build(parentPomFile, Sources.buildSource(parentPomFile)) + parent = build(true, parentPomFile, Sources.buildSource(parentPomFile)) .getProject(); } catch (ProjectBuildingException e) { // MNG-4488 where let invalid parents slide on by @@ -830,7 +866,7 @@ private void initParent(MavenProject project, ModelBuilderResult result) { } else { Artifact parentArtifact = project.getParentArtifact(); try { - parent = build(parentArtifact, false).getProject(); + parent = build(true, parentArtifact, false).getProject(); } catch (ProjectBuildingException e) { // MNG-4488 where let invalid parents slide on by if (logger.isDebugEnabled()) { @@ -1001,7 +1037,7 @@ private Model injectLifecycleBindings( projectBuildingHelper.selectProjectRealm(project); } - // build the regular repos after extensions are loaded to allow for custom layouts + // (re)build the regular repos after extensions are loaded to allow for custom layouts try { remoteRepositories = projectBuildingHelper.createArtifactRepositories( model3.getRepositories(), remoteRepositories, projectBuildingRequest); diff --git a/impl/maven-core/src/main/java/org/apache/maven/project/MavenProject.java b/impl/maven-core/src/main/java/org/apache/maven/project/MavenProject.java index aa682b9858a1..1ce8e3c5163b 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/project/MavenProject.java +++ b/impl/maven-core/src/main/java/org/apache/maven/project/MavenProject.java @@ -968,10 +968,16 @@ public List getPluginRepositories() { } public List getRemoteProjectRepositories() { + if (remoteProjectRepositories == null) { + remoteProjectRepositories = new ArrayList<>(); + } return remoteProjectRepositories; } public List getRemotePluginRepositories() { + if (remotePluginRepositories == null) { + remotePluginRepositories = new ArrayList<>(); + } return remotePluginRepositories; } diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/MappedList.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/MappedList.java index 629a8b1cda2c..2b16223caffa 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/MappedList.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/MappedList.java @@ -22,13 +22,15 @@ import java.util.List; import java.util.function.Function; +import static java.util.Objects.requireNonNull; + public class MappedList extends AbstractList { private final List list; private final Function mapper; public MappedList(List list, Function mapper) { - this.list = list; - this.mapper = mapper; + this.list = requireNonNull(list, "list"); + this.mapper = requireNonNull(mapper, "mapper"); } @Override diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng3477DependencyResolutionErrorMessageTest.java b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng3477DependencyResolutionErrorMessageTest.java index c61f02303afb..5ec5fa8c0f42 100644 --- a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng3477DependencyResolutionErrorMessageTest.java +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng3477DependencyResolutionErrorMessageTest.java @@ -96,7 +96,7 @@ void connectionProblemsPlugin() throws Exception { new String[] { ".*The following artifacts could not be resolved: org.apache.maven.its.plugins:maven-it-plugin-not-exists:pom:1.2.3 \\(absent\\): " + "Could not transfer artifact org.apache.maven.its.plugins:maven-it-plugin-not-exists:pom:1.2.3 from/to " - + "maven-core-it \\(http://localhost:.*/repo\\): Connection to http://localhost:.*2/repo/ refused.*" + + "central \\(http://localhost:.*/repo\\): Connection to http://localhost:.*2/repo/ refused.*" }, "pom-plugin.xml"); } diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4660ResumeFromTest.java b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4660ResumeFromTest.java index baa580cab359..0323edc680d3 100644 --- a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4660ResumeFromTest.java +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4660ResumeFromTest.java @@ -20,6 +20,7 @@ import java.io.File; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; /** @@ -40,7 +41,21 @@ public MavenITmng4660ResumeFromTest() { * module-a has not been packaged. * * @throws Exception in case of failure + * + * THIS TEST IS DISABLED + * this test (and expectation) goes against Maven nature: here it is expected that + * - you "cut" your reactor w/ -rf + * - but make Maven pick up "artifact" from some 4th place: not from Project Local Repository, not from + * Local Repository, and not from any Remote Repository, but from target/classes of left out subproject. + * + * Questions to tinker for those that are missing this use case: + * - if you want access to un-packaged subproject, why are you leaving it out from reactor? + * - if you do must leave it out, why are you not packaging it? + * - (maven3) why the hell are you not installing it? + * + * Recommended read: https://maveniverse.eu/blog/2025/03/17/never-say-never/ */ + @Disabled("This test goes against Maven (see javadoc above)") @Test public void testShouldResolveOutputDirectoryFromEarlierBuild() throws Exception { final File testDir = extractResources("/mng-4660-resume-from"); diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6090CIFriendlyTest.java b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6090CIFriendlyTest.java index 3b7ab90f1779..07f372ad7679 100644 --- a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6090CIFriendlyTest.java +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6090CIFriendlyTest.java @@ -56,7 +56,7 @@ public void testitShouldResolveTheDependenciesWithoutBuildConsumer() throws Exce verifier.addCliArgument("-Drevision=1.2"); verifier.addCliArgument("-Dmaven.consumer.pom=false"); verifier.setLogFileName("install-log.txt"); - verifier.addCliArguments("clean", "install"); + verifier.addCliArguments("clean", "package"); verifier.execute(); verifier.verifyErrorFreeLog(); @@ -82,7 +82,7 @@ public void testitShouldResolveTheDependenciesWithBuildConsumer() throws Excepti verifier.addCliArgument("-Drevision=1.2"); verifier.addCliArgument("-Dmaven.consumer.pom=true"); verifier.setLogFileName("install-log.txt"); - verifier.addCliArguments("clean", "install"); + verifier.addCliArguments("clean", "package"); verifier.execute(); verifier.verifyErrorFreeLog(); diff --git a/its/core-it-suite/src/test/resources-filtered/settings-remote.xml b/its/core-it-suite/src/test/resources-filtered/settings-remote.xml index d0d696e1f37f..7f714f84b59f 100644 --- a/its/core-it-suite/src/test/resources-filtered/settings-remote.xml +++ b/its/core-it-suite/src/test/resources-filtered/settings-remote.xml @@ -49,7 +49,7 @@ plugins/artifacts from test repos so use of these settings should be the excepti true - true + false @@ -62,7 +62,7 @@ plugins/artifacts from test repos so use of these settings should be the excepti true - true + false diff --git a/its/core-it-suite/src/test/resources-filtered/settings.xml b/its/core-it-suite/src/test/resources-filtered/settings.xml index 4a456c25076e..809f16331c10 100644 --- a/its/core-it-suite/src/test/resources-filtered/settings.xml +++ b/its/core-it-suite/src/test/resources-filtered/settings.xml @@ -51,7 +51,7 @@ own test repos or can employ the local repository (after bootstrapping). This co true - true + false diff --git a/its/core-it-suite/src/test/resources/mng-5175/settings-template.xml b/its/core-it-suite/src/test/resources/mng-5175/settings-template.xml index c6fc8614c87d..2dfd86fa3f75 100644 --- a/its/core-it-suite/src/test/resources/mng-5175/settings-template.xml +++ b/its/core-it-suite/src/test/resources/mng-5175/settings-template.xml @@ -20,5 +20,46 @@ http://localhost:@port@/archiva/repository/internal/ + + + + maven-core-it-repo + + + maven-core-it + http://unimportant + + true + ignore + + + true + ignore + + + + + + maven-core-it + http://localhost:@port@/repo + + true + ignore + + + true + ignore + + + + + + + maven-core-it-repo + diff --git a/its/core-it-suite/src/test/resources/mng-6090-ci-friendly/.mvn/.gitkeep b/its/core-it-suite/src/test/resources/mng-6090-ci-friendly/.mvn/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1