This is an automated email from the ASF dual-hosted git repository. cstamas pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/master by this push: new c7f22fe0d6 [MNG-8677] Bump to Resolver 2.0.8 and more (#2158) c7f22fe0d6 is described below commit c7f22fe0d66d69eea4631a8663b05b63b85591ac Author: Tamas Cservenak <ta...@cservenak.net> AuthorDate: Sat Apr 12 09:11:25 2025 +0200 [MNG-8677] Bump to Resolver 2.0.8 and more (#2158) Bump to Resolver 2.0.8, changes: * updates Maven to Resolver 2.0.8 * implements maven specific validator (new in Resolver 2.0.8) * applies required changes to suppliers --- https://issues.apache.org/jira/browse/MNG-8677 --- .../impl/resolver/validator/MavenValidator.java | 93 ++++++++++++++++++++++ .../resolver/validator/MavenValidatorFactory.java | 36 +++++++++ .../impl/standalone/RepositorySystemSupplier.java | 42 +++++++++- .../testing/stubs/RepositorySystemSupplier.java | 64 ++++++++++++++- .../.mvn/maven.properties | 2 + .../mng-5639-import-scope-pom-resolution/pom.xml | 5 -- pom.xml | 2 +- 7 files changed, 232 insertions(+), 12 deletions(-) diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/validator/MavenValidator.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/validator/MavenValidator.java new file mode 100644 index 0000000000..3726a7719f --- /dev/null +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/validator/MavenValidator.java @@ -0,0 +1,93 @@ +/* + * 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.impl.resolver.validator; + +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.metadata.Metadata; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.spi.validator.Validator; + +/** + * Simplest Maven specific validator that is meant to prevent un-interpolated + * elements enter resolver; if it does, is most likely some bug. + */ +public class MavenValidator implements Validator { + protected boolean containsPlaceholder(String value) { + return value != null && value.contains("${"); + } + + @Override + public void validateArtifact(Artifact artifact) throws IllegalArgumentException { + if (containsPlaceholder(artifact.getGroupId()) + || containsPlaceholder(artifact.getArtifactId()) + || containsPlaceholder(artifact.getVersion()) + || containsPlaceholder(artifact.getClassifier()) + || containsPlaceholder(artifact.getExtension())) { + throw new IllegalArgumentException("Not fully interpolated artifact " + artifact); + } + } + + @Override + public void validateMetadata(Metadata metadata) throws IllegalArgumentException { + if (containsPlaceholder(metadata.getGroupId()) + || containsPlaceholder(metadata.getArtifactId()) + || containsPlaceholder(metadata.getVersion()) + || containsPlaceholder(metadata.getType())) { + throw new IllegalArgumentException("Not fully interpolated metadata " + metadata); + } + } + + @Override + public void validateDependency(Dependency dependency) throws IllegalArgumentException { + Artifact artifact = dependency.getArtifact(); + if (containsPlaceholder(artifact.getGroupId()) + || containsPlaceholder(artifact.getArtifactId()) + || containsPlaceholder(artifact.getVersion()) + || containsPlaceholder(artifact.getClassifier()) + || containsPlaceholder(artifact.getExtension()) + || containsPlaceholder(dependency.getScope()) + || dependency.getExclusions().stream() + .anyMatch(e -> containsPlaceholder(e.getGroupId()) + || containsPlaceholder(e.getArtifactId()) + || containsPlaceholder(e.getClassifier()) + || containsPlaceholder(e.getExtension()))) { + throw new IllegalArgumentException("Not fully interpolated dependency " + dependency); + } + } + + @Override + public void validateLocalRepository(LocalRepository localRepository) throws IllegalArgumentException { + if (containsPlaceholder(localRepository.getBasePath().toString()) + || containsPlaceholder(localRepository.getContentType()) + || containsPlaceholder(localRepository.getId())) { + throw new IllegalArgumentException("Not fully interpolated local repository " + localRepository); + } + } + + @Override + public void validateRemoteRepository(RemoteRepository remoteRepository) throws IllegalArgumentException { + if (containsPlaceholder(remoteRepository.getUrl()) + || containsPlaceholder(remoteRepository.getContentType()) + || containsPlaceholder(remoteRepository.getId())) { + throw new IllegalArgumentException("Not fully interpolated remote repository " + remoteRepository); + } + } +} diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/validator/MavenValidatorFactory.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/validator/MavenValidatorFactory.java new file mode 100644 index 0000000000..57039f9b23 --- /dev/null +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/validator/MavenValidatorFactory.java @@ -0,0 +1,36 @@ +/* + * 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.impl.resolver.validator; + +import org.apache.maven.api.di.Named; +import org.apache.maven.api.di.Singleton; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.spi.validator.Validator; +import org.eclipse.aether.spi.validator.ValidatorFactory; + +@Named +@Singleton +public class MavenValidatorFactory implements ValidatorFactory { + private final MavenValidator instance = new MavenValidator(); + + @Override + public Validator newInstance(RepositorySystemSession repositorySystemSession) { + return instance; + } +} diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/standalone/RepositorySystemSupplier.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/standalone/RepositorySystemSupplier.java index 50832df1d6..7089b9fb66 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/standalone/RepositorySystemSupplier.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/standalone/RepositorySystemSupplier.java @@ -18,11 +18,13 @@ */ package org.apache.maven.impl.standalone; +import java.util.List; import java.util.Map; import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.di.Named; import org.apache.maven.api.di.Provides; +import org.apache.maven.impl.resolver.validator.MavenValidatorFactory; import org.eclipse.aether.RepositoryListener; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; @@ -40,6 +42,7 @@ import org.eclipse.aether.impl.RepositoryConnectorProvider; import org.eclipse.aether.impl.RepositoryEventDispatcher; import org.eclipse.aether.impl.RepositorySystemLifecycle; +import org.eclipse.aether.impl.RepositorySystemValidator; import org.eclipse.aether.impl.UpdateCheckManager; import org.eclipse.aether.impl.UpdatePolicyAnalyzer; import org.eclipse.aether.impl.VersionRangeResolver; @@ -62,6 +65,7 @@ import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider; import org.eclipse.aether.internal.impl.DefaultRepositorySystem; import org.eclipse.aether.internal.impl.DefaultRepositorySystemLifecycle; +import org.eclipse.aether.internal.impl.DefaultRepositorySystemValidator; import org.eclipse.aether.internal.impl.DefaultTrackingFileManager; import org.eclipse.aether.internal.impl.DefaultTransporterProvider; import org.eclipse.aether.internal.impl.DefaultUpdateCheckManager; @@ -85,8 +89,10 @@ import org.eclipse.aether.internal.impl.collect.bf.BfDependencyCollector; import org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector; import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager; +import org.eclipse.aether.internal.impl.filter.FilteringPipelineRepositoryConnectorFactory; import org.eclipse.aether.internal.impl.filter.GroupIdRemoteRepositoryFilterSource; import org.eclipse.aether.internal.impl.filter.PrefixesRemoteRepositoryFilterSource; +import org.eclipse.aether.internal.impl.offline.OfflinePipelineRepositoryConnectorFactory; import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory; import org.eclipse.aether.internal.impl.synccontext.named.NameMapper; import org.eclipse.aether.internal.impl.synccontext.named.NameMappers; @@ -105,6 +111,7 @@ import org.eclipse.aether.spi.artifact.generator.ArtifactGeneratorFactory; import org.eclipse.aether.spi.checksums.ProvidedChecksumsSource; import org.eclipse.aether.spi.checksums.TrustedChecksumsSource; +import org.eclipse.aether.spi.connector.PipelineRepositoryConnectorFactory; import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory; import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector; @@ -121,6 +128,7 @@ import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory; import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor; import org.eclipse.aether.spi.synccontext.SyncContextFactory; +import org.eclipse.aether.spi.validator.ValidatorFactory; /** * DI Bridge for Maven Resolver @@ -177,8 +185,8 @@ static UpdatePolicyAnalyzer newUpdatePolicyAnalyzer() { @Provides static RepositoryConnectorProvider newRepositoryConnectorProvider( Map<String, RepositoryConnectorFactory> connectorFactories, - RemoteRepositoryFilterManager remoteRepositoryFilterManager) { - return new DefaultRepositoryConnectorProvider(connectorFactories, remoteRepositoryFilterManager); + Map<String, PipelineRepositoryConnectorFactory> pipelineConnectorFactories) { + return new DefaultRepositoryConnectorProvider(connectorFactories, pipelineConnectorFactories); } @Named("basic") @@ -197,6 +205,20 @@ static BasicRepositoryConnectorFactory newBasicRepositoryConnectorFactory( providedChecksumsSources); } + @Named(OfflinePipelineRepositoryConnectorFactory.NAME) + @Provides + static OfflinePipelineRepositoryConnectorFactory newOfflinePipelineConnectorFactory( + OfflineController offlineController) { + return new OfflinePipelineRepositoryConnectorFactory(offlineController); + } + + @Named(FilteringPipelineRepositoryConnectorFactory.NAME) + @Provides + static FilteringPipelineRepositoryConnectorFactory newFilteringPipelineConnectorFactory( + RemoteRepositoryFilterManager remoteRepositoryFilterManager) { + return new FilteringPipelineRepositoryConnectorFactory(remoteRepositoryFilterManager); + } + @Provides static RepositoryLayoutProvider newRepositoryLayoutProvider(Map<String, RepositoryLayoutFactory> layoutFactories) { return new DefaultRepositoryLayoutProvider(layoutFactories); @@ -245,6 +267,16 @@ static PathProcessor newPathProcessor() { return new DefaultPathProcessor(); } + @Provides + static List<ValidatorFactory> newValidatorFactories() { + return List.of(new MavenValidatorFactory()); + } + + @Provides + static RepositorySystemValidator newRepositorySystemValidator(List<ValidatorFactory> validatorFactories) { + return new DefaultRepositorySystemValidator(validatorFactories); + } + @Provides static RepositorySystem newRepositorySystem( VersionResolver versionResolver, @@ -259,7 +291,8 @@ static RepositorySystem newRepositorySystem( SyncContextFactory syncContextFactory, RemoteRepositoryManager remoteRepositoryManager, RepositorySystemLifecycle repositorySystemLifecycle, - @Nullable Map<String, ArtifactDecoratorFactory> artifactDecoratorFactories) { + @Nullable Map<String, ArtifactDecoratorFactory> artifactDecoratorFactories, + RepositorySystemValidator repositorySystemValidator) { return new DefaultRepositorySystem( versionResolver, versionRangeResolver, @@ -273,7 +306,8 @@ static RepositorySystem newRepositorySystem( syncContextFactory, remoteRepositoryManager, repositorySystemLifecycle, - artifactDecoratorFactories != null ? artifactDecoratorFactories : Map.of()); + artifactDecoratorFactories != null ? artifactDecoratorFactories : Map.of(), + repositorySystemValidator); } @Provides diff --git a/impl/maven-testing/src/main/java/org/apache/maven/api/plugin/testing/stubs/RepositorySystemSupplier.java b/impl/maven-testing/src/main/java/org/apache/maven/api/plugin/testing/stubs/RepositorySystemSupplier.java index 5f7246db79..18a48a4b47 100644 --- a/impl/maven-testing/src/main/java/org/apache/maven/api/plugin/testing/stubs/RepositorySystemSupplier.java +++ b/impl/maven-testing/src/main/java/org/apache/maven/api/plugin/testing/stubs/RepositorySystemSupplier.java @@ -18,6 +18,7 @@ */ package org.apache.maven.api.plugin.testing.stubs; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -57,6 +58,7 @@ import org.apache.maven.impl.resolver.VersionsMetadataGeneratorFactory; import org.apache.maven.impl.resolver.relocation.DistributionManagementArtifactRelocationSource; import org.apache.maven.impl.resolver.relocation.UserPropertiesArtifactRelocationSource; +import org.apache.maven.impl.resolver.validator.MavenValidatorFactory; import org.eclipse.aether.RepositoryListener; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; @@ -74,6 +76,7 @@ import org.eclipse.aether.impl.RepositoryConnectorProvider; import org.eclipse.aether.impl.RepositoryEventDispatcher; import org.eclipse.aether.impl.RepositorySystemLifecycle; +import org.eclipse.aether.impl.RepositorySystemValidator; import org.eclipse.aether.impl.UpdateCheckManager; import org.eclipse.aether.impl.UpdatePolicyAnalyzer; import org.eclipse.aether.impl.VersionRangeResolver; @@ -96,6 +99,7 @@ import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider; import org.eclipse.aether.internal.impl.DefaultRepositorySystem; import org.eclipse.aether.internal.impl.DefaultRepositorySystemLifecycle; +import org.eclipse.aether.internal.impl.DefaultRepositorySystemValidator; import org.eclipse.aether.internal.impl.DefaultTrackingFileManager; import org.eclipse.aether.internal.impl.DefaultTransporterProvider; import org.eclipse.aether.internal.impl.DefaultUpdateCheckManager; @@ -119,8 +123,10 @@ import org.eclipse.aether.internal.impl.collect.bf.BfDependencyCollector; import org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector; import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager; +import org.eclipse.aether.internal.impl.filter.FilteringPipelineRepositoryConnectorFactory; import org.eclipse.aether.internal.impl.filter.GroupIdRemoteRepositoryFilterSource; import org.eclipse.aether.internal.impl.filter.PrefixesRemoteRepositoryFilterSource; +import org.eclipse.aether.internal.impl.offline.OfflinePipelineRepositoryConnectorFactory; import org.eclipse.aether.internal.impl.resolution.TrustedChecksumsArtifactResolverPostProcessor; import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory; import org.eclipse.aether.internal.impl.synccontext.named.NameMapper; @@ -141,6 +147,7 @@ import org.eclipse.aether.spi.artifact.transformer.ArtifactTransformer; import org.eclipse.aether.spi.checksums.ProvidedChecksumsSource; import org.eclipse.aether.spi.checksums.TrustedChecksumsSource; +import org.eclipse.aether.spi.connector.PipelineRepositoryConnectorFactory; import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory; import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector; @@ -157,6 +164,7 @@ import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory; import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor; import org.eclipse.aether.spi.synccontext.SyncContextFactory; +import org.eclipse.aether.spi.validator.ValidatorFactory; import org.eclipse.aether.transport.apache.ApacheTransporterFactory; import org.eclipse.aether.transport.file.FileTransporterFactory; import org.eclipse.aether.util.version.GenericVersionScheme; @@ -720,6 +728,27 @@ protected Map<String, RepositoryConnectorFactory> createRepositoryConnectorFacto return result; } + private Map<String, PipelineRepositoryConnectorFactory> pipelineRepositoryConnectorFactories; + + public final Map<String, PipelineRepositoryConnectorFactory> getPipelineRepositoryConnectorFactories() { + checkClosed(); + if (pipelineRepositoryConnectorFactories == null) { + pipelineRepositoryConnectorFactories = createPipelineRepositoryConnectorFactories(); + } + return pipelineRepositoryConnectorFactories; + } + + protected Map<String, PipelineRepositoryConnectorFactory> createPipelineRepositoryConnectorFactories() { + HashMap<String, PipelineRepositoryConnectorFactory> result = new HashMap<>(); + result.put( + OfflinePipelineRepositoryConnectorFactory.NAME, + new OfflinePipelineRepositoryConnectorFactory(getOfflineController())); + result.put( + FilteringPipelineRepositoryConnectorFactory.NAME, + new FilteringPipelineRepositoryConnectorFactory(getRemoteRepositoryFilterManager())); + return result; + } + private RepositoryConnectorProvider repositoryConnectorProvider; public final RepositoryConnectorProvider getRepositoryConnectorProvider() { @@ -732,7 +761,7 @@ public final RepositoryConnectorProvider getRepositoryConnectorProvider() { protected RepositoryConnectorProvider createRepositoryConnectorProvider() { return new DefaultRepositoryConnectorProvider( - getRepositoryConnectorFactories(), getRemoteRepositoryFilterManager()); + getRepositoryConnectorFactories(), getPipelineRepositoryConnectorFactories()); } private Installer installer; @@ -1081,6 +1110,36 @@ protected ModelBuilder createModelBuilder() { new DefaultRootLocator()); } + private RepositorySystemValidator repositorySystemValidator; + + public RepositorySystemValidator getRepositorySystemValidator() { + checkClosed(); + if (repositorySystemValidator == null) { + repositorySystemValidator = createRepositorySystemValidator(); + } + return repositorySystemValidator; + } + + protected RepositorySystemValidator createRepositorySystemValidator() { + return new DefaultRepositorySystemValidator(getValidatorFactories()); + } + + private List<ValidatorFactory> validatorFactories; + + public final List<ValidatorFactory> getValidatorFactories() { + checkClosed(); + if (validatorFactories == null) { + validatorFactories = createValidatorFactories(); + } + return validatorFactories; + } + + protected List<ValidatorFactory> createValidatorFactories() { + List<ValidatorFactory> result = new ArrayList<>(); + result.add(new MavenValidatorFactory()); + return result; + } + private RepositorySystem repositorySystem; public final RepositorySystem getRepositorySystem() { @@ -1105,7 +1164,8 @@ protected RepositorySystem createRepositorySystem() { getSyncContextFactory(), getRemoteRepositoryManager(), getRepositorySystemLifecycle(), - getArtifactDecoratorFactories()); + getArtifactDecoratorFactories(), + getRepositorySystemValidator()); } @Override diff --git a/its/core-it-suite/src/test/resources/mng-5639-import-scope-pom-resolution/.mvn/maven.properties b/its/core-it-suite/src/test/resources/mng-5639-import-scope-pom-resolution/.mvn/maven.properties new file mode 100644 index 0000000000..0344983373 --- /dev/null +++ b/its/core-it-suite/src/test/resources/mng-5639-import-scope-pom-resolution/.mvn/maven.properties @@ -0,0 +1,2 @@ +# Value corresponds to the folder name in this directory +repository.url.suffix.property = repo-set-by-property diff --git a/its/core-it-suite/src/test/resources/mng-5639-import-scope-pom-resolution/pom.xml b/its/core-it-suite/src/test/resources/mng-5639-import-scope-pom-resolution/pom.xml index ee0ca564cd..c119576f33 100644 --- a/its/core-it-suite/src/test/resources/mng-5639-import-scope-pom-resolution/pom.xml +++ b/its/core-it-suite/src/test/resources/mng-5639-import-scope-pom-resolution/pom.xml @@ -29,11 +29,6 @@ under the License. <description>Checks that an import POM in the dependencyManagement section can be successfully resolved from a repository defining a URL that contains a property.</description> - <properties> - <!-- Value corresponds to the folder name in this directory --> - <repository.url.suffix.property>repo-set-by-property</repository.url.suffix.property> - </properties> - <dependencyManagement> <dependencies> <dependency> diff --git a/pom.xml b/pom.xml index cdaed2b86e..5978a366ef 100644 --- a/pom.xml +++ b/pom.xml @@ -162,7 +162,7 @@ under the License. <plexusInterpolationVersion>1.28</plexusInterpolationVersion> <plexusTestingVersion>1.5.0</plexusTestingVersion> <plexusXmlVersion>4.1.0</plexusXmlVersion> - <resolverVersion>2.0.7</resolverVersion> + <resolverVersion>2.0.8</resolverVersion> <securityDispatcherVersion>4.1.0</securityDispatcherVersion> <sisuVersion>0.9.0.M3</sisuVersion> <slf4jVersion>2.0.17</slf4jVersion>