From 904caa4cf42ec7d4f8cfe629ada2867e1c96a023 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Wed, 7 Dec 2022 11:48:51 +0100 Subject: [PATCH 01/43] [MNG-6869] Initial idea --- .../java/org/apache/maven/cli/CLIManager.java | 7 ++ .../java/org/apache/maven/cli/MavenCli.java | 90 ++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java index 60ae83443e66..6a52089c3bc6 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java @@ -114,6 +114,8 @@ public class CLIManager { public static final String COLOR = "color"; + public static final String INSTALLATION_STATUS = "status"; + /** This option is deprecated and may be repurposed as Java debug in a future version. * Use {@code -X/--verbose} instead. */ @Deprecated @@ -296,6 +298,11 @@ public CLIManager() { .optionalArg(true) .desc("Defines the color mode of the output. Supported are 'auto', 'always', 'never'.") .build()); + options.addOption(Option.builder() + .longOpt(INSTALLATION_STATUS) + .optionalArg(true) + .desc("Display maven installation status") + .build()); // Deprecated options.addOption(Option.builder() diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index df491025a2d1..b92ec6182146 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -52,6 +52,9 @@ import org.apache.maven.BuildAbort; import org.apache.maven.InternalErrorException; import org.apache.maven.Maven; +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.building.FileSource; import org.apache.maven.building.Problem; import org.apache.maven.building.Source; @@ -74,16 +77,20 @@ import org.apache.maven.exception.ExceptionHandler; import org.apache.maven.exception.ExceptionSummary; import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.ExecutionListener; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequestPopulationException; import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenExecutionResult; +import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ProfileActivation; import org.apache.maven.execution.ProjectActivation; import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule; import org.apache.maven.extension.internal.CoreExports; import org.apache.maven.extension.internal.CoreExtensionEntry; +import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; +import org.apache.maven.internal.impl.DefaultSessionFactory; import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.logwrapper.LogLevelRecorder; import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory; @@ -110,6 +117,8 @@ import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.eclipse.aether.DefaultRepositoryCache; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.transfer.TransferListener; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; @@ -176,6 +185,14 @@ public class MavenCli { private CLIManager cliManager; + private PlexusContainer plexusContainer; + + private DefaultSessionFactory defaultSessionFactory; + + private MavenRepositorySystem mavenRepositorySystem; + + private DefaultRepositorySystemSessionFactory defaultRepositorySystemSessionFactory; + private static final Pattern NEXT_LINE = Pattern.compile("\r?\n"); public MavenCli() { @@ -391,6 +408,13 @@ private void informativeCommands(CliRequest cliRequest) throws ExitException { } throw new ExitException(0); } + + if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) + { + // Handle display? Might be worth the try + cliRequest.request.getRemoteRepositories(); + + } } private CommandLine cliMerge(CommandLine mavenConfig, CommandLine mavenCli) { @@ -641,6 +665,17 @@ protected void configure() { dispatcher = (DefaultSecDispatcher) container.lookup(SecDispatcher.class, "maven"); + defaultRepositorySystemSessionFactory = container.lookup( DefaultRepositorySystemSessionFactory.class ); + defaultSessionFactory = container.lookup( DefaultSessionFactory.class ); + mavenRepositorySystem = container.lookup( MavenRepositorySystem.class ); +// +// private DefaultSessionFactory defaultSessionFactory; +// +// private MavenRepositorySystem mavenRepositorySystem; +// private DefaultRepositorySystemSessionFactory defaultRepositorySystemSessionFactory; + + plexusContainer = container; + return container; } @@ -851,12 +886,65 @@ private void repository(CliRequest cliRequest) throws Exception { } private int execute(CliRequest cliRequest) throws MavenExecutionRequestPopulationException { - MavenExecutionRequest request = executionRequestPopulator.populateDefaults(cliRequest.request); + MavenExecutionRequest request = executionRequestPopulator.populateDefaults(cliRequest.request); // Populate request if (cliRequest.request.getRepositoryCache() == null) { cliRequest.request.setRepositoryCache(new DefaultRepositoryCache()); } + if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) + { + // We need the default values to verify it + boolean canMavenExecture = true; + final StringBuilder mavenInstallationErrors = new StringBuilder(); + + // TODO move this to a separate class or function. Refactor! + if ( !cliRequest.request.getLocalRepositoryPath().isDirectory() ) + { + canMavenExecture = false; + mavenInstallationErrors.append( "Local repository is not a directory.\n" ); + } + + if ( !cliRequest.request.getLocalRepositoryPath().canRead() ) + { + canMavenExecture = false; + mavenInstallationErrors.append( "No read permissions on local repository.\n" ); + } + + if ( !cliRequest.request.getLocalRepositoryPath().canWrite() ) + { + canMavenExecture = false; + mavenInstallationErrors.append( "No write permissions on local repository.\n" ); + } + + final DefaultRepositorySystemSession repoSession = + defaultRepositorySystemSessionFactory.newRepositorySession( request ); + MavenSession session = + new MavenSession( plexusContainer, repoSession, request, new DefaultMavenExecutionResult() ); + defaultSessionFactory.getSession( session ); + + final DefaultRepositorySystemSession defaultRepositorySystemSession = + defaultRepositorySystemSessionFactory.newRepositorySession( request ); + defaultRepositorySystemSession.isOffline(); + + List repos = RepositoryUtils.toRepos( cliRequest.request.getRemoteRepositories() ); + for ( ArtifactRepository remoteRepository : cliRequest.request.getRemoteRepositories() ) + { + // Need a way to verify proxy connection and remote repository + // 1. Verify Proxy + // 2. Verify authentication + // 3. Verify Mirror + + } + + if ( !canMavenExecture ) + { + slf4jLogger.warn( mavenInstallationErrors.toString() ); + return 1; + } + request.getLocalRepository(); + } + eventSpyDispatcher.onEvent(request); MavenExecutionResult result = maven.execute(request); From 2dab934a82f48d061d8771aa0dfddb863d1305cc Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Wed, 7 Dec 2022 12:15:50 +0100 Subject: [PATCH 02/43] [MNG-6869] Further brainstorming --- .../java/org/apache/maven/cli/CLIManager.java | 3 +-- .../java/org/apache/maven/cli/MavenCli.java | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java index 6a52089c3bc6..bfe828df8d7c 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java @@ -300,8 +300,7 @@ public CLIManager() { .build()); options.addOption(Option.builder() .longOpt(INSTALLATION_STATUS) - .optionalArg(true) - .desc("Display maven installation status") + .desc("Display Maven installation status") .build()); // Deprecated diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index b92ec6182146..7a982f436ecc 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -52,8 +52,8 @@ import org.apache.maven.BuildAbort; import org.apache.maven.InternalErrorException; import org.apache.maven.Maven; -import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.Authentication; import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.building.FileSource; import org.apache.maven.building.Problem; @@ -118,7 +118,6 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.eclipse.aether.DefaultRepositoryCache; import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.transfer.TransferListener; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; @@ -414,6 +413,7 @@ private void informativeCommands(CliRequest cliRequest) throws ExitException { // Handle display? Might be worth the try cliRequest.request.getRemoteRepositories(); + throw new ExitException( 0 ); } } @@ -892,6 +892,7 @@ private int execute(CliRequest cliRequest) throws MavenExecutionRequestPopulatio cliRequest.request.setRepositoryCache(new DefaultRepositoryCache()); } + // TODO move this while block to informativeCommands( ... ) if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) { // We need the default values to verify it @@ -927,16 +928,24 @@ private int execute(CliRequest cliRequest) throws MavenExecutionRequestPopulatio defaultRepositorySystemSessionFactory.newRepositorySession( request ); defaultRepositorySystemSession.isOffline(); - List repos = RepositoryUtils.toRepos( cliRequest.request.getRemoteRepositories() ); - for ( ArtifactRepository remoteRepository : cliRequest.request.getRemoteRepositories() ) + for ( ArtifactRepository artifactRepository : cliRequest.request.getRemoteRepositories() ) { // Need a way to verify proxy connection and remote repository // 1. Verify Proxy // 2. Verify authentication // 3. Verify Mirror + Authentication authentication = artifactRepository.getAuthentication(); + + String path = artifactRepository.getLayout().pathOfRemoteRepositoryMetadata( /* artifact metadata for org.apache.maven:apache-maven:3.8.6 */ null ); + + // TODO Idea: open an HTTP connection to the repository based on the connection details. + // Do not really attempt to resolve it here, because we don't know if this particular repository has the requested artifact. + // As long as return code is not 401, we're probably properly authenticated. This proves point 1 and 2. } + // TODO Now attempt to resolve org.apache.maven:apache-maven:3.8.6. This proves point 3. + if ( !canMavenExecture ) { slf4jLogger.warn( mavenInstallationErrors.toString() ); From 1082a0d1700942c5810c0e232410a62e9e834f4f Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Wed, 7 Dec 2022 13:07:25 +0100 Subject: [PATCH 03/43] [MNG-6869] Refactor local variable name --- .../src/main/java/org/apache/maven/cli/MavenCli.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 7a982f436ecc..1ca75c420093 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -896,25 +896,25 @@ private int execute(CliRequest cliRequest) throws MavenExecutionRequestPopulatio if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) { // We need the default values to verify it - boolean canMavenExecture = true; + boolean canMavenExecute = true; final StringBuilder mavenInstallationErrors = new StringBuilder(); // TODO move this to a separate class or function. Refactor! if ( !cliRequest.request.getLocalRepositoryPath().isDirectory() ) { - canMavenExecture = false; + canMavenExecute = false; mavenInstallationErrors.append( "Local repository is not a directory.\n" ); } if ( !cliRequest.request.getLocalRepositoryPath().canRead() ) { - canMavenExecture = false; + canMavenExecute = false; mavenInstallationErrors.append( "No read permissions on local repository.\n" ); } if ( !cliRequest.request.getLocalRepositoryPath().canWrite() ) { - canMavenExecture = false; + canMavenExecute = false; mavenInstallationErrors.append( "No write permissions on local repository.\n" ); } @@ -946,7 +946,7 @@ private int execute(CliRequest cliRequest) throws MavenExecutionRequestPopulatio // TODO Now attempt to resolve org.apache.maven:apache-maven:3.8.6. This proves point 3. - if ( !canMavenExecture ) + if ( !canMavenExecute ) { slf4jLogger.warn( mavenInstallationErrors.toString() ); return 1; From 8d46d92a966287be9a2c963cfa63bbfec52dc6f6 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 22 Dec 2022 13:25:13 +0100 Subject: [PATCH 04/43] [MNG-6969] WIP commit --- .../java/org/apache/maven/cli/MavenCli.java | 86 ++----- .../apache/maven/cli/MavenStatusCommand.java | 233 ++++++++++++++++++ 2 files changed, 250 insertions(+), 69 deletions(-) create mode 100644 maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 1ca75c420093..307dc1e18a09 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -52,8 +52,6 @@ import org.apache.maven.BuildAbort; import org.apache.maven.InternalErrorException; import org.apache.maven.Maven; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.Authentication; import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.building.FileSource; import org.apache.maven.building.Problem; @@ -77,13 +75,11 @@ import org.apache.maven.exception.ExceptionHandler; import org.apache.maven.exception.ExceptionSummary; import org.apache.maven.execution.DefaultMavenExecutionRequest; -import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.ExecutionListener; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequestPopulationException; import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenExecutionResult; -import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ProfileActivation; import org.apache.maven.execution.ProjectActivation; import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule; @@ -117,7 +113,6 @@ import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.eclipse.aether.DefaultRepositoryCache; -import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.transfer.TransferListener; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; @@ -292,6 +287,7 @@ public int doMain(CliRequest cliRequest) { informativeCommands(cliRequest); version(cliRequest); localContainer = container(cliRequest); + status(cliRequest); commands(cliRequest); configure(cliRequest); toolchains(cliRequest); @@ -407,12 +403,26 @@ private void informativeCommands(CliRequest cliRequest) throws ExitException { } throw new ExitException(0); } + } + private void status ( CliRequest cliRequest ) + throws Exception + { + slf4jLoggerFactory = LoggerFactory.getILoggerFactory(); if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) { - // Handle display? Might be worth the try - cliRequest.request.getRemoteRepositories(); + MavenStatusCommand mavenStatusCommand = new MavenStatusCommand( plexusContainer ); + final List mavenStatusIssues = mavenStatusCommand.verify( cliRequest ); + if ( !mavenStatusIssues.isEmpty() ) + { + for ( String issue : mavenStatusIssues ) + { + slf4jLogger.error( issue ); + } + throw new ExitException( 1 ); + } + slf4jLogger.info( "No installation issues found." ); throw new ExitException( 0 ); } } @@ -892,68 +902,6 @@ private int execute(CliRequest cliRequest) throws MavenExecutionRequestPopulatio cliRequest.request.setRepositoryCache(new DefaultRepositoryCache()); } - // TODO move this while block to informativeCommands( ... ) - if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) - { - // We need the default values to verify it - boolean canMavenExecute = true; - final StringBuilder mavenInstallationErrors = new StringBuilder(); - - // TODO move this to a separate class or function. Refactor! - if ( !cliRequest.request.getLocalRepositoryPath().isDirectory() ) - { - canMavenExecute = false; - mavenInstallationErrors.append( "Local repository is not a directory.\n" ); - } - - if ( !cliRequest.request.getLocalRepositoryPath().canRead() ) - { - canMavenExecute = false; - mavenInstallationErrors.append( "No read permissions on local repository.\n" ); - } - - if ( !cliRequest.request.getLocalRepositoryPath().canWrite() ) - { - canMavenExecute = false; - mavenInstallationErrors.append( "No write permissions on local repository.\n" ); - } - - final DefaultRepositorySystemSession repoSession = - defaultRepositorySystemSessionFactory.newRepositorySession( request ); - MavenSession session = - new MavenSession( plexusContainer, repoSession, request, new DefaultMavenExecutionResult() ); - defaultSessionFactory.getSession( session ); - - final DefaultRepositorySystemSession defaultRepositorySystemSession = - defaultRepositorySystemSessionFactory.newRepositorySession( request ); - defaultRepositorySystemSession.isOffline(); - - for ( ArtifactRepository artifactRepository : cliRequest.request.getRemoteRepositories() ) - { - // Need a way to verify proxy connection and remote repository - // 1. Verify Proxy - // 2. Verify authentication - // 3. Verify Mirror - - Authentication authentication = artifactRepository.getAuthentication(); - - String path = artifactRepository.getLayout().pathOfRemoteRepositoryMetadata( /* artifact metadata for org.apache.maven:apache-maven:3.8.6 */ null ); - - // TODO Idea: open an HTTP connection to the repository based on the connection details. - // Do not really attempt to resolve it here, because we don't know if this particular repository has the requested artifact. - // As long as return code is not 401, we're probably properly authenticated. This proves point 1 and 2. - } - - // TODO Now attempt to resolve org.apache.maven:apache-maven:3.8.6. This proves point 3. - - if ( !canMavenExecute ) - { - slf4jLogger.warn( mavenInstallationErrors.toString() ); - return 1; - } - request.getLocalRepository(); - } - eventSpyDispatcher.onEvent(request); MavenExecutionResult result = maven.execute(request); diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java new file mode 100644 index 000000000000..e24ad5731f08 --- /dev/null +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -0,0 +1,233 @@ +package org.apache.maven.cli; + +/* + * 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. + */ + +import org.apache.maven.api.services.ArtifactFactoryRequest; +import org.apache.maven.api.services.ArtifactResolver; +import org.apache.maven.api.services.ArtifactResolverRequest; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.Authentication; +import org.apache.maven.cli.configuration.ConfigurationProcessor; +import org.apache.maven.execution.DefaultMavenExecutionResult; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.MavenExecutionRequestPopulator; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; +import org.apache.maven.internal.impl.DefaultArtifactCoordinate; +import org.apache.maven.internal.impl.DefaultArtifactFactory; +import org.apache.maven.internal.impl.DefaultSessionFactory; +import org.apache.maven.repository.Proxy; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class MavenStatusCommand +{ + /** + * In order to verify artifacts can be downloaded from the remote repositories we want to resolve an actual + * artifact. The Apache Maven artifact was chosen as it eventually, be it by proxy, mirror or directly, will be + * gathered from the central repository. The version is chosen arbitrarily since any listed should work. + */ + private final Artifact apacheMavenArtifact; + private final MavenExecutionRequestPopulator mavenExecutionRequestPopulator; + private final ConfigurationProcessor configurationProcessor; + private final ArtifactResolver artifactResolver; + private final DefaultSessionFactory defaultSessionFactory; + private final DefaultRepositorySystemSessionFactory repoSession; + private final Logger logger; + private final PlexusContainer container; + + public MavenStatusCommand( PlexusContainer container ) throws ComponentLookupException + { + this.container = container; + mavenExecutionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class ); + logger = LoggerFactory.getILoggerFactory().getLogger( MavenStatusCommand.class.getName() ); + configurationProcessor = container.lookup( ConfigurationProcessor.class ); + artifactResolver = container.lookup( ArtifactResolver.class ); + defaultSessionFactory = container.lookup( DefaultSessionFactory.class ); + repoSession = container.lookup( DefaultRepositorySystemSessionFactory.class ); + + ArtifactHandlerManager manager = container.lookup( ArtifactHandlerManager.class ); + apacheMavenArtifact = new DefaultArtifact( "org.apache.maven", "apache-maven", "3.8.6", + null, "pom", null, manager.getArtifactHandler( "pom" ) ); + } + + public List verify( CliRequest cliRequest ) + throws Exception + { + // Populate the cliRequest with defaults and user settings + final MavenExecutionRequest mavenExecutionRequest = + mavenExecutionRequestPopulator.populateDefaults( cliRequest.request ); + configurationProcessor.process( cliRequest ); + + final List localRepositoryIssues = + verifyLocalRepository( cliRequest.getRequest().getLocalRepositoryPath() ); + final List remoteRepositoryIssues = + verifyRemoteRepositoryConnections( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); + final List artifactResolutionIssues = verifyArtifactResolution(); + + // Collect all issues into a single list + return Stream.of( localRepositoryIssues, remoteRepositoryIssues, artifactResolutionIssues ) + .flatMap( Collection::stream ) + .collect( Collectors.toList() ); + } + + private List verifyArtifactResolution() + { + final List issues = new ArrayList<>(); + + return issues; + } + + // TODO: is becoming a large method + private List verifyRemoteRepositoryConnections( List remoteRepositories, + MavenExecutionRequest mavenExecutionRequest ) + throws IOException + { + final List issues = new ArrayList<>(); + + for ( ArtifactRepository artifactRepository : remoteRepositories ) + { + final String protocol = artifactRepository.getProtocol(); + if ( !"http".equals( protocol ) && !"https".equals( protocol ) ) + { + final String unsupportedProtocolWarning = + String.format( "No status checks available for protocol %s.", protocol ); + logger.info( unsupportedProtocolWarning ); + continue; + } + + final String artifactPath = artifactRepository.getLayout().pathOf( apacheMavenArtifact ); + final String urlToRemoteRepository = + String.join( "/", artifactRepository.getUrl(), artifactPath ); + + + MavenSession session = new MavenSession( container, repoSession.newRepositorySession( mavenExecutionRequest ), + mavenExecutionRequest, new DefaultMavenExecutionResult() ); + + final ArtifactFactoryRequest artifactRequest = ArtifactFactoryRequest.builder() + .groupId( apacheMavenArtifact.getGroupId() ) + .artifactId( apacheMavenArtifact.getArtifactId() ) + .classifier( apacheMavenArtifact.getClassifier() ) + .extension( "pom" ) + .version( apacheMavenArtifact.getVersion() ) + .type( apacheMavenArtifact.getType() ) + .build(); + + final org.apache.maven.api.Artifact artifact = new DefaultArtifactFactory().create( artifactRequest ); + +// new DefaultArtifactCoordinate( session.getSession(), artifact); + +// new org.eclipse.aether.artifact.DefaultArtifact( +// apacheMavenArtifact.getGroupId(), +// apacheMavenArtifact.getArtifactId(), +// apacheMavenArtifact.getClassifier(), +// "pom", +// apacheMavenArtifact.getVersion(), +// ); +// +// artifactResolver.resolve(session, ) + + URL url = new URL( urlToRemoteRepository ); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod( "GET" ); + + Authentication auth = artifactRepository.getAuthentication(); + if ( auth != null ) + { + connection.setRequestProperty( "Authorization", + createAuthorizationHeaderValue( auth.getUsername(), auth.getPassword() ) ); + } + + if ( artifactRepository.getProxy() != null ) + { + final Proxy proxy = artifactRepository.getProxy(); + connection.setRequestProperty( "Proxy-Authorization", + createAuthorizationHeaderValue( proxy.getUserName(), proxy.getPassword() ) ); + } + + int responseCode = connection.getResponseCode(); + + if ( !isAuthenticated( responseCode ) ) + { + final String authenticationIssue = + String.format( "Authentication failed. Remote repository responded with response code %d.", + responseCode ); + issues.add( authenticationIssue ); + } + connection.disconnect(); + } + + return issues; + } + + private static String createAuthorizationHeaderValue( String userName, String password ) + { + final String userNamePassword = userName + ":" + password; + return "Basic " + Base64.getEncoder().encodeToString( userNamePassword.getBytes() ); + } + + private boolean isAuthenticated( int responseCode ) + { + // TODO: maybe 404 as well as it might be used to hide the existence of the page to + // a user without adequate privileges or not correctly authenticated. + // Just catch entire 400-499 range to avoid missing errors? + return responseCode != 401 + && responseCode != 403 + && responseCode != 407; + } + + private List verifyLocalRepository( File localRepositoryPath ) + { + final List issues = new ArrayList<>(); + if ( !localRepositoryPath.isDirectory() ) + { + issues.add( "Local repository is not a directory." ); + } + + if ( !localRepositoryPath.canRead() ) + { + issues.add( "No read permissions on local repository." ); + } + + if ( !localRepositoryPath.canWrite() ) + { + issues.add( "No write permissions on local repository.\n" ); + } + + return issues; + } +} + From 9aaf62f6c19a8334f441541473a8e639a71ccf6f Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 22 Dec 2022 14:23:17 +0100 Subject: [PATCH 05/43] [MNG-6869] Correct way to find local repo path --- .../main/java/org/apache/maven/cli/MavenStatusCommand.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index e24ad5731f08..0343dc2c228f 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -91,9 +91,10 @@ public List verify( CliRequest cliRequest ) final MavenExecutionRequest mavenExecutionRequest = mavenExecutionRequestPopulator.populateDefaults( cliRequest.request ); configurationProcessor.process( cliRequest ); + final String localRepositoryURL = cliRequest.getRequest().getLocalRepository().getUrl(); final List localRepositoryIssues = - verifyLocalRepository( cliRequest.getRequest().getLocalRepositoryPath() ); + verifyLocalRepository( new File(URI.create(localRepositoryURL)) ); final List remoteRepositoryIssues = verifyRemoteRepositoryConnections( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); final List artifactResolutionIssues = verifyArtifactResolution(); @@ -211,6 +212,7 @@ private boolean isAuthenticated( int responseCode ) private List verifyLocalRepository( File localRepositoryPath ) { + // TODO Rewrite using java.nio.file.Path final List issues = new ArrayList<>(); if ( !localRepositoryPath.isDirectory() ) { From 57c70206f98fac144e08a45a62f2d842e472c6fc Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 22 Dec 2022 14:57:18 +0100 Subject: [PATCH 06/43] [MNG-6869] Use java.nio instead of java.io --- .../apache/maven/cli/MavenStatusCommand.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 0343dc2c228f..a66b9dfe6a39 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -21,7 +21,6 @@ import org.apache.maven.api.services.ArtifactFactoryRequest; import org.apache.maven.api.services.ArtifactResolver; -import org.apache.maven.api.services.ArtifactResolverRequest; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; @@ -33,7 +32,6 @@ import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenSession; import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; -import org.apache.maven.internal.impl.DefaultArtifactCoordinate; import org.apache.maven.internal.impl.DefaultArtifactFactory; import org.apache.maven.internal.impl.DefaultSessionFactory; import org.apache.maven.repository.Proxy; @@ -42,10 +40,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; +import java.net.URI; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Base64; import java.util.Collection; @@ -94,7 +95,7 @@ public List verify( CliRequest cliRequest ) final String localRepositoryURL = cliRequest.getRequest().getLocalRepository().getUrl(); final List localRepositoryIssues = - verifyLocalRepository( new File(URI.create(localRepositoryURL)) ); + verifyLocalRepository( URI.create( localRepositoryURL )); final List remoteRepositoryIssues = verifyRemoteRepositoryConnections( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); final List artifactResolutionIssues = verifyArtifactResolution(); @@ -210,21 +211,22 @@ private boolean isAuthenticated( int responseCode ) && responseCode != 407; } - private List verifyLocalRepository( File localRepositoryPath ) + private List verifyLocalRepository( URI localRepositoryURI ) { - // TODO Rewrite using java.nio.file.Path final List issues = new ArrayList<>(); - if ( !localRepositoryPath.isDirectory() ) + Path localRepositoryPath = Paths.get( localRepositoryURI ); + + if ( !Files.isDirectory( localRepositoryPath ) ) { issues.add( "Local repository is not a directory." ); } - if ( !localRepositoryPath.canRead() ) + if ( !Files.isReadable( localRepositoryPath ) ) { issues.add( "No read permissions on local repository." ); } - if ( !localRepositoryPath.canWrite() ) + if ( !Files.isWritable( localRepositoryPath ) ) { issues.add( "No write permissions on local repository.\n" ); } From 55f35fd2b97d8f25267fb0941f20cbd67e10fe11 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 22 Dec 2022 16:11:07 +0100 Subject: [PATCH 07/43] [MNG-6869] Use java.nio instead of java.io --- .../java/org/apache/maven/cli/MavenStatusCommand.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index a66b9dfe6a39..7d5c5e44d3ed 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -92,10 +92,11 @@ public List verify( CliRequest cliRequest ) final MavenExecutionRequest mavenExecutionRequest = mavenExecutionRequestPopulator.populateDefaults( cliRequest.request ); configurationProcessor.process( cliRequest ); - final String localRepositoryURL = cliRequest.getRequest().getLocalRepository().getUrl(); + + final ArtifactRepository localRepository = cliRequest.getRequest().getLocalRepository(); final List localRepositoryIssues = - verifyLocalRepository( URI.create( localRepositoryURL )); + verifyLocalRepository( Paths.get( URI.create( localRepository.getUrl() ) ) ); final List remoteRepositoryIssues = verifyRemoteRepositoryConnections( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); final List artifactResolutionIssues = verifyArtifactResolution(); @@ -211,10 +212,9 @@ private boolean isAuthenticated( int responseCode ) && responseCode != 407; } - private List verifyLocalRepository( URI localRepositoryURI ) + private List verifyLocalRepository( final Path localRepositoryPath ) { final List issues = new ArrayList<>(); - Path localRepositoryPath = Paths.get( localRepositoryURI ); if ( !Files.isDirectory( localRepositoryPath ) ) { @@ -228,7 +228,7 @@ private List verifyLocalRepository( URI localRepositoryURI ) if ( !Files.isWritable( localRepositoryPath ) ) { - issues.add( "No write permissions on local repository.\n" ); + issues.add( "No write permissions on local repository." ); } return issues; From fdcce304116556ce5424d17b1b74afa4c28bcd65 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 22 Dec 2022 16:20:39 +0100 Subject: [PATCH 08/43] [MNG-6869] Implement verification of artifact resolution (WIP) --- .../impl/DefaultArtifactCoordinate.java | 5 +- .../java/org/apache/maven/cli/MavenCli.java | 4 +- .../apache/maven/cli/MavenStatusCommand.java | 154 +++++++----------- 3 files changed, 60 insertions(+), 103 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java index d76b161766ce..030a28e5399b 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java @@ -21,6 +21,7 @@ import java.util.Objects; import org.apache.maven.api.ArtifactCoordinate; +import org.apache.maven.api.Session; import org.apache.maven.api.VersionRange; import org.apache.maven.api.annotations.Nonnull; @@ -30,11 +31,11 @@ * A wrapper class around a maven resolver artifact. */ public class DefaultArtifactCoordinate implements ArtifactCoordinate { - private final @Nonnull AbstractSession session; + private final @Nonnull Session session; private final @Nonnull org.eclipse.aether.artifact.Artifact coordinate; public DefaultArtifactCoordinate( - @Nonnull AbstractSession session, @Nonnull org.eclipse.aether.artifact.Artifact coordinate) { + @Nonnull Session session, @Nonnull org.eclipse.aether.artifact.Artifact coordinate) { this.session = nonNull(session, "session can not be null"); this.coordinate = nonNull(coordinate, "coordinate can not be null"); } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 307dc1e18a09..54d2db91bdce 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -287,11 +287,11 @@ public int doMain(CliRequest cliRequest) { informativeCommands(cliRequest); version(cliRequest); localContainer = container(cliRequest); - status(cliRequest); commands(cliRequest); configure(cliRequest); toolchains(cliRequest); populateRequest(cliRequest); + status(cliRequest); encryption(cliRequest); repository(cliRequest); return execute(cliRequest); @@ -405,7 +405,7 @@ private void informativeCommands(CliRequest cliRequest) throws ExitException { } } - private void status ( CliRequest cliRequest ) + private void status( CliRequest cliRequest ) throws Exception { slf4jLoggerFactory = LoggerFactory.getILoggerFactory(); diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 7d5c5e44d3ed..cca4ba46cd9b 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -19,37 +19,37 @@ * under the License. */ -import org.apache.maven.api.services.ArtifactFactoryRequest; +import org.apache.maven.api.services.ArtifactResolverException; +import org.apache.maven.api.services.ArtifactResolverResult; +import org.apache.maven.internal.impl.DefaultSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.apache.maven.api.ArtifactCoordinate; +import org.apache.maven.api.Session; import org.apache.maven.api.services.ArtifactResolver; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.DefaultArtifact; -import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.Authentication; import org.apache.maven.cli.configuration.ConfigurationProcessor; import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenSession; import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; -import org.apache.maven.internal.impl.DefaultArtifactFactory; +import org.apache.maven.internal.impl.DefaultArtifactCoordinate; import org.apache.maven.internal.impl.DefaultSessionFactory; -import org.apache.maven.repository.Proxy; +import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.eclipse.aether.resolution.ArtifactResolutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.net.HttpURLConnection; import java.net.URI; -import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Base64; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -61,7 +61,13 @@ public class MavenStatusCommand * artifact. The Apache Maven artifact was chosen as it eventually, be it by proxy, mirror or directly, will be * gathered from the central repository. The version is chosen arbitrarily since any listed should work. */ - private final Artifact apacheMavenArtifact; + private static final Artifact artifact = new DefaultArtifact( + "org.apache.maven", + "apache-maven", + null, + "pom", + "3.8.6" + ); private final MavenExecutionRequestPopulator mavenExecutionRequestPopulator; private final ConfigurationProcessor configurationProcessor; private final ArtifactResolver artifactResolver; @@ -69,6 +75,7 @@ public class MavenStatusCommand private final DefaultRepositorySystemSessionFactory repoSession; private final Logger logger; private final PlexusContainer container; + private final SessionScope sessionScope; public MavenStatusCommand( PlexusContainer container ) throws ComponentLookupException { @@ -79,27 +86,26 @@ public MavenStatusCommand( PlexusContainer container ) throws ComponentLookupExc artifactResolver = container.lookup( ArtifactResolver.class ); defaultSessionFactory = container.lookup( DefaultSessionFactory.class ); repoSession = container.lookup( DefaultRepositorySystemSessionFactory.class ); - - ArtifactHandlerManager manager = container.lookup( ArtifactHandlerManager.class ); - apacheMavenArtifact = new DefaultArtifact( "org.apache.maven", "apache-maven", "3.8.6", - null, "pom", null, manager.getArtifactHandler( "pom" ) ); + sessionScope = container.lookup( SessionScope.class ); } - public List verify( CliRequest cliRequest ) + public List verify(CliRequest cliRequest ) throws Exception { // Populate the cliRequest with defaults and user settings final MavenExecutionRequest mavenExecutionRequest = mavenExecutionRequestPopulator.populateDefaults( cliRequest.request ); - configurationProcessor.process( cliRequest ); + // TODO If an active profile defines more remote repositories, they do not yet show in mavenExecutionRequest. + // configurationProcessor.process( cliRequest ); final ArtifactRepository localRepository = cliRequest.getRequest().getLocalRepository(); final List localRepositoryIssues = verifyLocalRepository( Paths.get( URI.create( localRepository.getUrl() ) ) ); final List remoteRepositoryIssues = - verifyRemoteRepositoryConnections( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); - final List artifactResolutionIssues = verifyArtifactResolution(); + verifyRemoteRepositoryConnections(); + final List artifactResolutionIssues = + verifyArtifactResolution( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); // Collect all issues into a single list return Stream.of( localRepositoryIssues, remoteRepositoryIssues, artifactResolutionIssues ) @@ -107,17 +113,15 @@ public List verify( CliRequest cliRequest ) .collect( Collectors.toList() ); } - private List verifyArtifactResolution() + private List verifyRemoteRepositoryConnections() { final List issues = new ArrayList<>(); return issues; } - // TODO: is becoming a large method - private List verifyRemoteRepositoryConnections( List remoteRepositories, - MavenExecutionRequest mavenExecutionRequest ) - throws IOException + private List verifyArtifactResolution( List remoteRepositories, + MavenExecutionRequest mavenExecutionRequest ) { final List issues = new ArrayList<>(); @@ -132,86 +136,38 @@ private List verifyRemoteRepositoryConnections( List continue; } - final String artifactPath = artifactRepository.getLayout().pathOf( apacheMavenArtifact ); - final String urlToRemoteRepository = - String.join( "/", artifactRepository.getUrl(), artifactPath ); - - - MavenSession session = new MavenSession( container, repoSession.newRepositorySession( mavenExecutionRequest ), - mavenExecutionRequest, new DefaultMavenExecutionResult() ); - - final ArtifactFactoryRequest artifactRequest = ArtifactFactoryRequest.builder() - .groupId( apacheMavenArtifact.getGroupId() ) - .artifactId( apacheMavenArtifact.getArtifactId() ) - .classifier( apacheMavenArtifact.getClassifier() ) - .extension( "pom" ) - .version( apacheMavenArtifact.getVersion() ) - .type( apacheMavenArtifact.getType() ) - .build(); - - final org.apache.maven.api.Artifact artifact = new DefaultArtifactFactory().create( artifactRequest ); - -// new DefaultArtifactCoordinate( session.getSession(), artifact); - -// new org.eclipse.aether.artifact.DefaultArtifact( -// apacheMavenArtifact.getGroupId(), -// apacheMavenArtifact.getArtifactId(), -// apacheMavenArtifact.getClassifier(), -// "pom", -// apacheMavenArtifact.getVersion(), -// ); -// -// artifactResolver.resolve(session, ) - - URL url = new URL( urlToRemoteRepository ); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod( "GET" ); - - Authentication auth = artifactRepository.getAuthentication(); - if ( auth != null ) - { - connection.setRequestProperty( "Authorization", - createAuthorizationHeaderValue( auth.getUsername(), auth.getPassword() ) ); + final Session session = this.defaultSessionFactory.getSession( + new MavenSession( + container, + repoSession.newRepositorySession(mavenExecutionRequest), + mavenExecutionRequest, + new DefaultMavenExecutionResult() + ) + ); + + sessionScope.enter(); + try { + sessionScope.seed(DefaultSession.class, (DefaultSession) session); + + final ArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(session, artifact); + final ArtifactResolverResult resolverResult = artifactResolver.resolve(session, Collections.singleton(artifactCoordinate)); + + resolverResult.getArtifacts().keySet().forEach(entry -> { + logger.info("Successfully resolved {} from {}", entry.toString(), artifactRepository.getUrl()); + }); + + } catch (ArtifactResolverException are) { + final boolean isArtifactResolutionException = are.getCause() instanceof ArtifactResolutionException; + final String message = isArtifactResolutionException ? are.getCause().getMessage() : are.getMessage(); + issues.add(message); + } finally { + sessionScope.exit(); } - - if ( artifactRepository.getProxy() != null ) - { - final Proxy proxy = artifactRepository.getProxy(); - connection.setRequestProperty( "Proxy-Authorization", - createAuthorizationHeaderValue( proxy.getUserName(), proxy.getPassword() ) ); - } - - int responseCode = connection.getResponseCode(); - - if ( !isAuthenticated( responseCode ) ) - { - final String authenticationIssue = - String.format( "Authentication failed. Remote repository responded with response code %d.", - responseCode ); - issues.add( authenticationIssue ); - } - connection.disconnect(); } return issues; } - private static String createAuthorizationHeaderValue( String userName, String password ) - { - final String userNamePassword = userName + ":" + password; - return "Basic " + Base64.getEncoder().encodeToString( userNamePassword.getBytes() ); - } - - private boolean isAuthenticated( int responseCode ) - { - // TODO: maybe 404 as well as it might be used to hide the existence of the page to - // a user without adequate privileges or not correctly authenticated. - // Just catch entire 400-499 range to avoid missing errors? - return responseCode != 401 - && responseCode != 403 - && responseCode != 407; - } - private List verifyLocalRepository( final Path localRepositoryPath ) { final List issues = new ArrayList<>(); From e4ec5172070cfe400ae40fe603b3fa8f48d05fee Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 12 Jan 2023 15:47:04 +0100 Subject: [PATCH 09/43] [MNG-6869] Test artifact resolution with temporary local repository --- .../java/org/apache/maven/cli/MavenCli.java | 25 ++++- .../apache/maven/cli/MavenStatusCommand.java | 98 +++++++++---------- 2 files changed, 66 insertions(+), 57 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 54d2db91bdce..6305a0eef6b8 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -1245,7 +1245,7 @@ private MavenExecutionRequest populateRequest(CliRequest cliRequest, MavenExecut performProjectActivation(commandLine, request.getProjectActivation()); performProfileActivation(commandLine, request.getProfileActivation()); - final String localRepositoryPath = determineLocalRepositoryPath(request); + final String localRepositoryPath = determineLocalRepositoryPath(cliRequest); if (localRepositoryPath != null) { request.setLocalRepositoryPath(localRepositoryPath); } @@ -1276,10 +1276,25 @@ private MavenExecutionRequest populateRequest(CliRequest cliRequest, MavenExecut return request; } - private String determineLocalRepositoryPath(final MavenExecutionRequest request) { - String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); - if (userDefinedLocalRepo != null) { - return userDefinedLocalRepo; + private String determineLocalRepositoryPath(final CliRequest cliRequest) { + final MavenExecutionRequest request = cliRequest.getRequest(); + if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) + { + try { + return Files.createTempDirectory("mvn-status").toAbsolutePath().toString(); + } catch (IOException ioe) { + final Logger logger = slf4jLoggerFactory.getLogger(getClass().getName()); + logger.debug("Could not create temporary local repository", ioe); + logger.warn("Artifact resolution test is less accurate as it may user earlier resolution results."); + } + } + else + { + String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); + if (userDefinedLocalRepo != null) + { + return userDefinedLocalRepo; + } } // TODO Investigate why this can also be a Java system property and not just a Maven user property like diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index cca4ba46cd9b..5198f652887a 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -22,13 +22,10 @@ import org.apache.maven.api.services.ArtifactResolverException; import org.apache.maven.api.services.ArtifactResolverResult; import org.apache.maven.internal.impl.DefaultSession; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.DefaultArtifact; import org.apache.maven.api.ArtifactCoordinate; import org.apache.maven.api.Session; import org.apache.maven.api.services.ArtifactResolver; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.cli.configuration.ConfigurationProcessor; import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequestPopulator; @@ -39,7 +36,11 @@ import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; +import org.eclipse.aether.transfer.ArtifactNotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,7 +70,6 @@ public class MavenStatusCommand "3.8.6" ); private final MavenExecutionRequestPopulator mavenExecutionRequestPopulator; - private final ConfigurationProcessor configurationProcessor; private final ArtifactResolver artifactResolver; private final DefaultSessionFactory defaultSessionFactory; private final DefaultRepositorySystemSessionFactory repoSession; @@ -77,12 +77,11 @@ public class MavenStatusCommand private final PlexusContainer container; private final SessionScope sessionScope; - public MavenStatusCommand( PlexusContainer container ) throws ComponentLookupException + public MavenStatusCommand( final PlexusContainer container ) throws ComponentLookupException { this.container = container; mavenExecutionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class ); logger = LoggerFactory.getILoggerFactory().getLogger( MavenStatusCommand.class.getName() ); - configurationProcessor = container.lookup( ConfigurationProcessor.class ); artifactResolver = container.lookup( ArtifactResolver.class ); defaultSessionFactory = container.lookup( DefaultSessionFactory.class ); repoSession = container.lookup( DefaultRepositorySystemSessionFactory.class ); @@ -95,8 +94,6 @@ public List verify(CliRequest cliRequest ) // Populate the cliRequest with defaults and user settings final MavenExecutionRequest mavenExecutionRequest = mavenExecutionRequestPopulator.populateDefaults( cliRequest.request ); - // TODO If an active profile defines more remote repositories, they do not yet show in mavenExecutionRequest. - // configurationProcessor.process( cliRequest ); final ArtifactRepository localRepository = cliRequest.getRequest().getLocalRepository(); @@ -104,8 +101,7 @@ public List verify(CliRequest cliRequest ) verifyLocalRepository( Paths.get( URI.create( localRepository.getUrl() ) ) ); final List remoteRepositoryIssues = verifyRemoteRepositoryConnections(); - final List artifactResolutionIssues = - verifyArtifactResolution( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); + final List artifactResolutionIssues = verifyArtifactResolution( mavenExecutionRequest ); // Collect all issues into a single list return Stream.of( localRepositoryIssues, remoteRepositoryIssues, artifactResolutionIssues ) @@ -120,52 +116,50 @@ private List verifyRemoteRepositoryConnections() return issues; } - private List verifyArtifactResolution( List remoteRepositories, - MavenExecutionRequest mavenExecutionRequest ) + private List verifyArtifactResolution( final MavenExecutionRequest mavenExecutionRequest ) { - final List issues = new ArrayList<>(); + final Session session = this.defaultSessionFactory.getSession( + new MavenSession( + container, + repoSession.newRepositorySession(mavenExecutionRequest), + mavenExecutionRequest, + new DefaultMavenExecutionResult() + ) + ); + + sessionScope.enter(); + try { + sessionScope.seed(DefaultSession.class, (DefaultSession) session); + + final ArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(session, artifact); + final ArtifactResolverResult resolverResult = artifactResolver.resolve(session, Collections.singleton(artifactCoordinate)); + + resolverResult.getArtifacts().forEach((key, value) -> { + logger.debug("Successfully resolved {} to {}", key.toString(), value.toString()); + }); + + return Collections.emptyList(); + } catch (ArtifactResolverException are) { + return extractErrorMessagesFromArtifactResolverException(are); + } finally { + sessionScope.exit(); + } + } - for ( ArtifactRepository artifactRepository : remoteRepositories ) + private List extractErrorMessagesFromArtifactResolverException(final Exception exception) { + final boolean isArtifactResolutionException = exception.getCause() instanceof ArtifactResolutionException; + if (isArtifactResolutionException) { - final String protocol = artifactRepository.getProtocol(); - if ( !"http".equals( protocol ) && !"https".equals( protocol ) ) - { - final String unsupportedProtocolWarning = - String.format( "No status checks available for protocol %s.", protocol ); - logger.info( unsupportedProtocolWarning ); - continue; - } - - final Session session = this.defaultSessionFactory.getSession( - new MavenSession( - container, - repoSession.newRepositorySession(mavenExecutionRequest), - mavenExecutionRequest, - new DefaultMavenExecutionResult() - ) - ); - - sessionScope.enter(); - try { - sessionScope.seed(DefaultSession.class, (DefaultSession) session); - - final ArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(session, artifact); - final ArtifactResolverResult resolverResult = artifactResolver.resolve(session, Collections.singleton(artifactCoordinate)); - - resolverResult.getArtifacts().keySet().forEach(entry -> { - logger.info("Successfully resolved {} from {}", entry.toString(), artifactRepository.getUrl()); - }); - - } catch (ArtifactResolverException are) { - final boolean isArtifactResolutionException = are.getCause() instanceof ArtifactResolutionException; - final String message = isArtifactResolutionException ? are.getCause().getMessage() : are.getMessage(); - issues.add(message); - } finally { - sessionScope.exit(); - } + final ArtifactResolutionException are = (ArtifactResolutionException) exception.getCause(); + return (are).getResults().stream() + .map(ArtifactResult::getExceptions) + .flatMap(List::stream) + .map(ArtifactNotFoundException.class::cast) + .map(Throwable::getMessage) + .collect(Collectors.toList()); + } else { + return Collections.singletonList(exception.getMessage()); } - - return issues; } private List verifyLocalRepository( final Path localRepositoryPath ) From 77526f5af9149f680dbed203e4ccedbd28a4630c Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 12 Jan 2023 16:21:05 +0100 Subject: [PATCH 10/43] [MNG-6869] Setup checks for remote connections --- .../apache/maven/cli/MavenStatusCommand.java | 91 ++++++++++++++++++- 1 file changed, 87 insertions(+), 4 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 5198f652887a..61b92a8460bb 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -19,9 +19,15 @@ * under the License. */ +import org.apache.maven.RepositoryUtils; import org.apache.maven.api.services.ArtifactResolverException; import org.apache.maven.api.services.ArtifactResolverResult; +import org.apache.maven.artifact.repository.Authentication; +import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.internal.impl.DefaultSession; +import org.apache.maven.settings.Mirror; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; import org.apache.maven.api.ArtifactCoordinate; import org.apache.maven.api.Session; import org.apache.maven.api.services.ArtifactResolver; @@ -33,22 +39,28 @@ import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; import org.apache.maven.internal.impl.DefaultArtifactCoordinate; import org.apache.maven.internal.impl.DefaultSessionFactory; +import org.apache.maven.repository.Proxy; import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.resolution.ArtifactResolutionException; import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.aether.transfer.ArtifactNotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.net.Authenticator; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; import java.net.URI; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -100,7 +112,7 @@ public List verify(CliRequest cliRequest ) final List localRepositoryIssues = verifyLocalRepository( Paths.get( URI.create( localRepository.getUrl() ) ) ); final List remoteRepositoryIssues = - verifyRemoteRepositoryConnections(); + verifyRemoteRepositoryConnections( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest.getMirrors() ); final List artifactResolutionIssues = verifyArtifactResolution( mavenExecutionRequest ); // Collect all issues into a single list @@ -109,13 +121,84 @@ public List verify(CliRequest cliRequest ) .collect( Collectors.toList() ); } - private List verifyRemoteRepositoryConnections() + private List verifyRemoteRepositoryConnections( List remoteRepositories, + List mirrors ) + throws IOException { final List issues = new ArrayList<>(); + for ( ArtifactRepository remoteRepository : remoteRepositories ) + { + // Only support HTTP and HTTPS + final String protocol = remoteRepository.getProtocol(); + if ( !"http".equals( protocol ) && !"https".equals( protocol ) ) + { + final String unsupportedProtocolWarning = + String.format( "No status checks available for protocol %s.", protocol ); + logger.info( unsupportedProtocolWarning ); + continue; + } + + final Mirror mirror = MavenRepositorySystem.getMirror( remoteRepository, mirrors ); + //TODO get path of mirror to resolve url + + // Setup connection + final String artifactUrl = remoteRepository.getUrl() + "/" + remoteRepository.getLayout().pathOf( RepositoryUtils.toArtifact( artifact ) ); + URL url = new URL( artifactUrl ); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + if (remoteRepository.getProxy() != null) { + // Use proxy + final Proxy proxy = remoteRepository.getProxy(); + final java.net.Proxy javaProxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, new InetSocketAddress(proxy.getHost(), proxy.getPort())); + Authenticator authenticator = new Authenticator() { + public PasswordAuthentication getPasswordAuthentication() { + return (new PasswordAuthentication( proxy.getUserName(), proxy.getPassword().toCharArray())); // Password might be encrypted, if so decrypt + } + }; + Authenticator.setDefault(authenticator); + connection = (HttpURLConnection) url.openConnection(javaProxy); + } + + if (remoteRepository.getAuthentication() != null) { + final Authentication authentication = remoteRepository.getAuthentication(); + if (authentication.getPrivateKey() != null) + { + // We probably need to use a certificate, use password if there is one + } + else + { + // Add Basic Authorization header instead + String credentials = authentication.getUsername() + ":" + authentication.getPassword(); + connection.setRequestProperty( "Authorization", createAuthorizationHeader( credentials )); + } + } + + // Send request + connection.setRequestMethod("GET"); + final int responseCode = connection.getResponseCode(); + + // Report response + if (responseCode == 200 || responseCode == 404) + { + logger.info( "Successfully connected to {}", remoteRepository.getUrl() ); + } + else + { + final String issue + = String.format( "%s responded with code %d.", remoteRepository.getUrl(), responseCode ); + issues.add( issue ); + } + + } + return issues; } + private static String createAuthorizationHeader( String credentials ) + { + return "Basic " + Base64.getEncoder().encodeToString( credentials.getBytes()); + } + private List verifyArtifactResolution( final MavenExecutionRequest mavenExecutionRequest ) { final Session session = this.defaultSessionFactory.getSession( From fbbcc20cb810e8a183b53b6181e0a1d2c21c14e1 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 12 Jan 2023 16:11:19 +0100 Subject: [PATCH 11/43] [MNG-6869] Formatting --- .../java/org/apache/maven/cli/MavenCli.java | 19 ++++--- .../apache/maven/cli/MavenStatusCommand.java | 57 +++++++++++-------- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 6305a0eef6b8..86fb11163f31 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -1280,18 +1280,21 @@ private String determineLocalRepositoryPath(final CliRequest cliRequest) { final MavenExecutionRequest request = cliRequest.getRequest(); if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) { - try { - return Files.createTempDirectory("mvn-status").toAbsolutePath().toString(); - } catch (IOException ioe) { - final Logger logger = slf4jLoggerFactory.getLogger(getClass().getName()); - logger.debug("Could not create temporary local repository", ioe); - logger.warn("Artifact resolution test is less accurate as it may user earlier resolution results."); + try + { + return Files.createTempDirectory( "mvn-status" ).toAbsolutePath().toString(); + } + catch ( IOException ioe ) + { + final Logger logger = slf4jLoggerFactory.getLogger( getClass().getName() ); + logger.debug( "Could not create temporary local repository", ioe ); + logger.warn( "Artifact resolution test is less accurate as it may user earlier resolution results." ); } } else { - String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); - if (userDefinedLocalRepo != null) + String userDefinedLocalRepo = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY ); + if ( userDefinedLocalRepo != null ) { return userDefinedLocalRepo; } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 61b92a8460bb..067cc163471f 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -74,7 +74,7 @@ public class MavenStatusCommand * artifact. The Apache Maven artifact was chosen as it eventually, be it by proxy, mirror or directly, will be * gathered from the central repository. The version is chosen arbitrarily since any listed should work. */ - private static final Artifact artifact = new DefaultArtifact( + private static final Artifact APACHE_MAVEN_ARTIFACT = new DefaultArtifact( "org.apache.maven", "apache-maven", null, @@ -100,7 +100,7 @@ public MavenStatusCommand( final PlexusContainer container ) throws ComponentLoo sessionScope = container.lookup( SessionScope.class ); } - public List verify(CliRequest cliRequest ) + public List verify( CliRequest cliRequest ) throws Exception { // Populate the cliRequest with defaults and user settings @@ -204,44 +204,53 @@ private List verifyArtifactResolution( final MavenExecutionRequest maven final Session session = this.defaultSessionFactory.getSession( new MavenSession( container, - repoSession.newRepositorySession(mavenExecutionRequest), + repoSession.newRepositorySession( mavenExecutionRequest ), mavenExecutionRequest, new DefaultMavenExecutionResult() ) ); sessionScope.enter(); - try { - sessionScope.seed(DefaultSession.class, (DefaultSession) session); + try + { + sessionScope.seed( DefaultSession.class, (DefaultSession) session ); - final ArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(session, artifact); - final ArtifactResolverResult resolverResult = artifactResolver.resolve(session, Collections.singleton(artifactCoordinate)); + ArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate( session, APACHE_MAVEN_ARTIFACT ); + ArtifactResolverResult resolverResult = artifactResolver.resolve( session, + Collections.singleton( artifactCoordinate ) ); - resolverResult.getArtifacts().forEach((key, value) -> { - logger.debug("Successfully resolved {} to {}", key.toString(), value.toString()); - }); + resolverResult.getArtifacts().forEach( ( key, value ) -> + logger.debug( "Successfully resolved {} to {}", key.toString(), value.toString() ) + ); return Collections.emptyList(); - } catch (ArtifactResolverException are) { - return extractErrorMessagesFromArtifactResolverException(are); - } finally { + } + catch ( ArtifactResolverException are ) + { + return extractErrorMessagesFromArtifactResolverException( are ); + } + finally + { sessionScope.exit(); } } - private List extractErrorMessagesFromArtifactResolverException(final Exception exception) { + private List extractErrorMessagesFromArtifactResolverException( final Exception exception ) + { final boolean isArtifactResolutionException = exception.getCause() instanceof ArtifactResolutionException; - if (isArtifactResolutionException) + if ( isArtifactResolutionException ) + { + final ArtifactResolutionException are = ( ArtifactResolutionException ) exception.getCause(); + return are.getResults().stream() + .map( ArtifactResult::getExceptions ) + .flatMap( List::stream ) + .map( ArtifactNotFoundException.class::cast ) + .map( Throwable::getMessage ) + .collect( Collectors.toList() ); + } + else { - final ArtifactResolutionException are = (ArtifactResolutionException) exception.getCause(); - return (are).getResults().stream() - .map(ArtifactResult::getExceptions) - .flatMap(List::stream) - .map(ArtifactNotFoundException.class::cast) - .map(Throwable::getMessage) - .collect(Collectors.toList()); - } else { - return Collections.singletonList(exception.getMessage()); + return Collections.singletonList( exception.getMessage() ); } } From ba9354a90a2c27d42c191dee84d3d8deb8510d0e Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 12 Jan 2023 16:11:38 +0100 Subject: [PATCH 12/43] [MNG-6869] Refactor: rename method --- .../main/java/org/apache/maven/cli/MavenStatusCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 067cc163471f..7c5d43fc95cf 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -227,7 +227,7 @@ private List verifyArtifactResolution( final MavenExecutionRequest maven } catch ( ArtifactResolverException are ) { - return extractErrorMessagesFromArtifactResolverException( are ); + return extractIssuesFromArtifactResolverException( are ); } finally { @@ -235,7 +235,7 @@ private List verifyArtifactResolution( final MavenExecutionRequest maven } } - private List extractErrorMessagesFromArtifactResolverException( final Exception exception ) + private List extractIssuesFromArtifactResolverException( final Exception exception ) { final boolean isArtifactResolutionException = exception.getCause() instanceof ArtifactResolutionException; if ( isArtifactResolutionException ) From 85b090725cab7f1f69ea1ff560f7e27e805dd38a Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Mon, 16 Jan 2023 07:48:11 +0100 Subject: [PATCH 13/43] [MNG-6869] Formatting --- .../main/java/org/apache/maven/cli/MavenStatusCommand.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 7c5d43fc95cf..59e02ab8de65 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -111,8 +111,8 @@ public List verify( CliRequest cliRequest ) final List localRepositoryIssues = verifyLocalRepository( Paths.get( URI.create( localRepository.getUrl() ) ) ); - final List remoteRepositoryIssues = - verifyRemoteRepositoryConnections( cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest.getMirrors() ); + final List remoteRepositoryIssues = verifyRemoteRepositoryConnections( + cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest.getMirrors() ); final List artifactResolutionIssues = verifyArtifactResolution( mavenExecutionRequest ); // Collect all issues into a single list @@ -143,7 +143,8 @@ private List verifyRemoteRepositoryConnections( List //TODO get path of mirror to resolve url // Setup connection - final String artifactUrl = remoteRepository.getUrl() + "/" + remoteRepository.getLayout().pathOf( RepositoryUtils.toArtifact( artifact ) ); + final String artifactUrl = remoteRepository.getUrl() + + "/" + remoteRepository.getLayout().pathOf( RepositoryUtils.toArtifact( APACHE_MAVEN_ARTIFACT ) ); URL url = new URL( artifactUrl ); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); if (remoteRepository.getProxy() != null) { From 12a6b4b0b81eb66394ca08786a0573dfbd263c0e Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 26 Jan 2023 15:09:27 +0100 Subject: [PATCH 14/43] [MNG-6869] Verify connection to remote repositories --- .../apache/maven/cli/MavenStatusCommand.java | 97 ++------------- .../RemoteRepositoryConnectionVerifier.java | 115 ++++++++++++++++++ 2 files changed, 128 insertions(+), 84 deletions(-) create mode 100644 maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 59e02ab8de65..f7b41df8c313 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -19,13 +19,10 @@ * under the License. */ -import org.apache.maven.RepositoryUtils; import org.apache.maven.api.services.ArtifactResolverException; import org.apache.maven.api.services.ArtifactResolverResult; -import org.apache.maven.artifact.repository.Authentication; -import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.internal.impl.DefaultSession; -import org.apache.maven.settings.Mirror; +import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; import org.apache.maven.api.ArtifactCoordinate; @@ -39,7 +36,6 @@ import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; import org.apache.maven.internal.impl.DefaultArtifactCoordinate; import org.apache.maven.internal.impl.DefaultSessionFactory; -import org.apache.maven.repository.Proxy; import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; @@ -49,18 +45,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.net.Authenticator; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.PasswordAuthentication; import java.net.URI; -import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -74,7 +63,7 @@ public class MavenStatusCommand * artifact. The Apache Maven artifact was chosen as it eventually, be it by proxy, mirror or directly, will be * gathered from the central repository. The version is chosen arbitrarily since any listed should work. */ - private static final Artifact APACHE_MAVEN_ARTIFACT = new DefaultArtifact( + public static final Artifact APACHE_MAVEN_ARTIFACT = new DefaultArtifact( "org.apache.maven", "apache-maven", null, @@ -83,6 +72,7 @@ public class MavenStatusCommand ); private final MavenExecutionRequestPopulator mavenExecutionRequestPopulator; private final ArtifactResolver artifactResolver; + private final RemoteRepositoryConnectionVerifier remoteRepositoryConnectionVerifier; private final DefaultSessionFactory defaultSessionFactory; private final DefaultRepositorySystemSessionFactory repoSession; private final Logger logger; @@ -92,6 +82,7 @@ public class MavenStatusCommand public MavenStatusCommand( final PlexusContainer container ) throws ComponentLookupException { this.container = container; + this.remoteRepositoryConnectionVerifier = new RemoteRepositoryConnectionVerifier( container ); mavenExecutionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class ); logger = LoggerFactory.getILoggerFactory().getLogger( MavenStatusCommand.class.getName() ); artifactResolver = container.lookup( ArtifactResolver.class ); @@ -112,7 +103,7 @@ public List verify( CliRequest cliRequest ) final List localRepositoryIssues = verifyLocalRepository( Paths.get( URI.create( localRepository.getUrl() ) ) ); final List remoteRepositoryIssues = verifyRemoteRepositoryConnections( - cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest.getMirrors() ); + cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); final List artifactResolutionIssues = verifyArtifactResolution( mavenExecutionRequest ); // Collect all issues into a single list @@ -121,85 +112,22 @@ public List verify( CliRequest cliRequest ) .collect( Collectors.toList() ); } - private List verifyRemoteRepositoryConnections( List remoteRepositories, - List mirrors ) - throws IOException - { + private List verifyRemoteRepositoryConnections( + final List remoteRepositories, + final MavenExecutionRequest mavenExecutionRequest + ) { final List issues = new ArrayList<>(); for ( ArtifactRepository remoteRepository : remoteRepositories ) { - // Only support HTTP and HTTPS - final String protocol = remoteRepository.getProtocol(); - if ( !"http".equals( protocol ) && !"https".equals( protocol ) ) - { - final String unsupportedProtocolWarning = - String.format( "No status checks available for protocol %s.", protocol ); - logger.info( unsupportedProtocolWarning ); - continue; - } - - final Mirror mirror = MavenRepositorySystem.getMirror( remoteRepository, mirrors ); - //TODO get path of mirror to resolve url - - // Setup connection - final String artifactUrl = remoteRepository.getUrl() - + "/" + remoteRepository.getLayout().pathOf( RepositoryUtils.toArtifact( APACHE_MAVEN_ARTIFACT ) ); - URL url = new URL( artifactUrl ); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - if (remoteRepository.getProxy() != null) { - // Use proxy - final Proxy proxy = remoteRepository.getProxy(); - final java.net.Proxy javaProxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, new InetSocketAddress(proxy.getHost(), proxy.getPort())); - Authenticator authenticator = new Authenticator() { - public PasswordAuthentication getPasswordAuthentication() { - return (new PasswordAuthentication( proxy.getUserName(), proxy.getPassword().toCharArray())); // Password might be encrypted, if so decrypt - } - }; - Authenticator.setDefault(authenticator); - connection = (HttpURLConnection) url.openConnection(javaProxy); - } - - if (remoteRepository.getAuthentication() != null) { - final Authentication authentication = remoteRepository.getAuthentication(); - if (authentication.getPrivateKey() != null) - { - // We probably need to use a certificate, use password if there is one - } - else - { - // Add Basic Authorization header instead - String credentials = authentication.getUsername() + ":" + authentication.getPassword(); - connection.setRequestProperty( "Authorization", createAuthorizationHeader( credentials )); - } - } - - // Send request - connection.setRequestMethod("GET"); - final int responseCode = connection.getResponseCode(); - - // Report response - if (responseCode == 200 || responseCode == 404) - { - logger.info( "Successfully connected to {}", remoteRepository.getUrl() ); - } - else - { - final String issue - = String.format( "%s responded with code %d.", remoteRepository.getUrl(), responseCode ); - issues.add( issue ); - } - + final RepositorySystemSession repositorySession = repoSession.newRepositorySession( mavenExecutionRequest ); + remoteRepositoryConnectionVerifier.verifyConnectionToRemoteRepository( repositorySession, remoteRepository ) + .ifPresent( issues::add ); } return issues; } - private static String createAuthorizationHeader( String credentials ) - { - return "Basic " + Base64.getEncoder().encodeToString( credentials.getBytes()); - } - private List verifyArtifactResolution( final MavenExecutionRequest mavenExecutionRequest ) { final Session session = this.defaultSessionFactory.getSession( @@ -233,6 +161,7 @@ private List verifyArtifactResolution( final MavenExecutionRequest maven finally { sessionScope.exit(); + logger.info( "Artifact resolution check completed" ); } } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java new file mode 100644 index 000000000000..16d825d6ee99 --- /dev/null +++ b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java @@ -0,0 +1,115 @@ +package org.apache.maven.cli; + +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.spi.connector.transport.GetTask; +import org.eclipse.aether.spi.connector.transport.Transporter; +import org.eclipse.aether.spi.connector.transport.TransporterProvider; +import org.eclipse.aether.transfer.NoTransporterException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URI; +import java.util.Optional; + +/** + * Helper class to verify connection to a remote repository. + */ +public class RemoteRepositoryConnectionVerifier { + private static final Artifact APACHE_MAVEN_ARTIFACT = MavenStatusCommand.APACHE_MAVEN_ARTIFACT; + private final Logger logger; + private final TransporterProvider transporterProvider; + + public RemoteRepositoryConnectionVerifier( final PlexusContainer container ) throws ComponentLookupException + { + this.logger = LoggerFactory.getILoggerFactory().getLogger( RemoteRepositoryConnectionVerifier.class.getName() ); + this.transporterProvider = container.lookup(TransporterProvider.class); + } + + private boolean isCentralOrMirrorOfCentral( final RemoteRepository remoteRepository ) { + return "central".equals( remoteRepository.getId() ) || + remoteRepository.getMirroredRepositories().stream() + .map( RemoteRepository::getId ) + .anyMatch( "central"::equals ); + } + + public Optional verifyConnectionToRemoteRepository( final RepositorySystemSession session, + final ArtifactRepository artifactRepository ) + { + final RemoteRepository repository = RepositoryUtils.toRepo( artifactRepository ); + + final String artifactPath; + + if ( isCentralOrMirrorOfCentral( repository ) ) { + // We can be sure the Apache Maven artifact should be resolvable. + artifactPath = artifactRepository.getLayout().pathOf( RepositoryUtils.toArtifact( APACHE_MAVEN_ARTIFACT ) ); + } else { + // We cannot be sure about any artifact that lives here. + artifactPath = "/"; + } + + try { + final Transporter transporter = transporterProvider.newTransporter( session, repository ); + final Optional maybeIssue = verifyConnectionUsingTransport( transporter, repository, artifactPath ); + + if ( !maybeIssue.isPresent() ) { + logger.info( "Connection check for {} [{}] completed", repository.getId(), repository.getUrl() ); + } + + return maybeIssue; + } catch ( final NoTransporterException nte ) { + final String message = String.format( + "There is no compatible transport for remote repository %s with location %s", + repository.getId(), + repository.getUrl() + ); + return Optional.of( message ); + } + } + + private Optional verifyConnectionUsingTransport( + final Transporter transporter, + final RemoteRepository remoteRepository, + final String artifactPath + ) { + try { + final GetTask task = new GetTask( URI.create( artifactPath ) ); + transporter.get( task ); + return Optional.empty(); + } catch ( final Exception e ) { + return classifyException( remoteRepository, e ); + } + } + + private Optional classifyException( final RemoteRepository remoteRepository, final Exception e ) { + final String message = e.getMessage(); + final String repositoryUrl = remoteRepository.getUrl(); + + final boolean resourceMissing = StringUtils.contains( message, "resource missing" ); + + if ( isCentralOrMirrorOfCentral( remoteRepository ) && resourceMissing ) { + final String issue = String.format( "Connection to %s possible, but expected artifact %s cannot be resolved", + repositoryUrl, APACHE_MAVEN_ARTIFACT ); + return Optional.of( issue ); + + } else if ( resourceMissing ) { + // We tried to resolve the artifact from a repository that does not necessarily host it. + logger.warn( "Connection to {} possible, but artifact {} not found", repositoryUrl, APACHE_MAVEN_ARTIFACT ); + return Optional.empty(); + + } else if ( StringUtils.contains( message, "authentication failed" ) ) { + final String issue = String.format( "Connection to %s possible, but authentication failed", repositoryUrl ); + return Optional.of(issue); + + } + + logger.error( "Error connecting to repository {} [{}]", remoteRepository.getId(), repositoryUrl, e ); + return Optional.of( "Unknown issue: " + e.getMessage() ); + } +} From 140a63ccd43f067d53db2426d72e4e22d6272166 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 26 Jan 2023 15:30:07 +0100 Subject: [PATCH 15/43] [MNG-6869] Reformat with Spotless --- .../java/org/apache/maven/cli/CLIManager.java | 2 +- .../java/org/apache/maven/cli/MavenCli.java | 71 +++---- .../apache/maven/cli/MavenStatusCommand.java | 190 ++++++++---------- .../RemoteRepositoryConnectionVerifier.java | 105 +++++----- 4 files changed, 170 insertions(+), 198 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java index bfe828df8d7c..4bcd3c23e8a2 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java @@ -114,7 +114,7 @@ public class CLIManager { public static final String COLOR = "color"; - public static final String INSTALLATION_STATUS = "status"; + public static final String INSTALLATION_STATUS = "status"; /** This option is deprecated and may be repurposed as Java debug in a future version. * Use {@code -X/--verbose} instead. */ diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 86fb11163f31..c3b71f3cee30 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -405,25 +405,20 @@ private void informativeCommands(CliRequest cliRequest) throws ExitException { } } - private void status( CliRequest cliRequest ) - throws Exception - { + private void status(CliRequest cliRequest) throws Exception { slf4jLoggerFactory = LoggerFactory.getILoggerFactory(); - if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) - { - MavenStatusCommand mavenStatusCommand = new MavenStatusCommand( plexusContainer ); - final List mavenStatusIssues = mavenStatusCommand.verify( cliRequest ); - if ( !mavenStatusIssues.isEmpty() ) - { - for ( String issue : mavenStatusIssues ) - { - slf4jLogger.error( issue ); + if (cliRequest.commandLine.hasOption(CLIManager.INSTALLATION_STATUS)) { + MavenStatusCommand mavenStatusCommand = new MavenStatusCommand(plexusContainer); + final List mavenStatusIssues = mavenStatusCommand.verify(cliRequest); + if (!mavenStatusIssues.isEmpty()) { + for (String issue : mavenStatusIssues) { + slf4jLogger.error(issue); } - throw new ExitException( 1 ); + throw new ExitException(1); } - slf4jLogger.info( "No installation issues found." ); - throw new ExitException( 0 ); + slf4jLogger.info("No installation issues found."); + throw new ExitException(0); } } @@ -675,14 +670,14 @@ protected void configure() { dispatcher = (DefaultSecDispatcher) container.lookup(SecDispatcher.class, "maven"); - defaultRepositorySystemSessionFactory = container.lookup( DefaultRepositorySystemSessionFactory.class ); - defaultSessionFactory = container.lookup( DefaultSessionFactory.class ); - mavenRepositorySystem = container.lookup( MavenRepositorySystem.class ); -// -// private DefaultSessionFactory defaultSessionFactory; -// -// private MavenRepositorySystem mavenRepositorySystem; -// private DefaultRepositorySystemSessionFactory defaultRepositorySystemSessionFactory; + defaultRepositorySystemSessionFactory = container.lookup(DefaultRepositorySystemSessionFactory.class); + defaultSessionFactory = container.lookup(DefaultSessionFactory.class); + mavenRepositorySystem = container.lookup(MavenRepositorySystem.class); + // + // private DefaultSessionFactory defaultSessionFactory; + // + // private MavenRepositorySystem mavenRepositorySystem; + // private DefaultRepositorySystemSessionFactory defaultRepositorySystemSessionFactory; plexusContainer = container; @@ -896,7 +891,8 @@ private void repository(CliRequest cliRequest) throws Exception { } private int execute(CliRequest cliRequest) throws MavenExecutionRequestPopulationException { - MavenExecutionRequest request = executionRequestPopulator.populateDefaults(cliRequest.request); // Populate request + MavenExecutionRequest request = + executionRequestPopulator.populateDefaults(cliRequest.request); // Populate request if (cliRequest.request.getRepositoryCache() == null) { cliRequest.request.setRepositoryCache(new DefaultRepositoryCache()); @@ -1278,24 +1274,17 @@ private MavenExecutionRequest populateRequest(CliRequest cliRequest, MavenExecut private String determineLocalRepositoryPath(final CliRequest cliRequest) { final MavenExecutionRequest request = cliRequest.getRequest(); - if ( cliRequest.commandLine.hasOption( CLIManager.INSTALLATION_STATUS ) ) - { - try - { - return Files.createTempDirectory( "mvn-status" ).toAbsolutePath().toString(); - } - catch ( IOException ioe ) - { - final Logger logger = slf4jLoggerFactory.getLogger( getClass().getName() ); - logger.debug( "Could not create temporary local repository", ioe ); - logger.warn( "Artifact resolution test is less accurate as it may user earlier resolution results." ); + if (cliRequest.commandLine.hasOption(CLIManager.INSTALLATION_STATUS)) { + try { + return Files.createTempDirectory("mvn-status").toAbsolutePath().toString(); + } catch (IOException ioe) { + final Logger logger = slf4jLoggerFactory.getLogger(getClass().getName()); + logger.debug("Could not create temporary local repository", ioe); + logger.warn("Artifact resolution test is less accurate as it may user earlier resolution results."); } - } - else - { - String userDefinedLocalRepo = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY ); - if ( userDefinedLocalRepo != null ) - { + } else { + String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); + if (userDefinedLocalRepo != null) { return userDefinedLocalRepo; } } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index f7b41df8c313..cfcd700891f3 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -1,5 +1,3 @@ -package org.apache.maven.cli; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -9,7 +7,7 @@ * "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 + * 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 @@ -18,16 +16,24 @@ * specific language governing permissions and limitations * under the License. */ +package org.apache.maven.cli; + +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; -import org.apache.maven.api.services.ArtifactResolverException; -import org.apache.maven.api.services.ArtifactResolverResult; -import org.apache.maven.internal.impl.DefaultSession; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.DefaultArtifact; import org.apache.maven.api.ArtifactCoordinate; import org.apache.maven.api.Session; import org.apache.maven.api.services.ArtifactResolver; +import org.apache.maven.api.services.ArtifactResolverException; +import org.apache.maven.api.services.ArtifactResolverResult; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; @@ -35,41 +41,29 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; import org.apache.maven.internal.impl.DefaultArtifactCoordinate; +import org.apache.maven.internal.impl.DefaultSession; import org.apache.maven.internal.impl.DefaultSessionFactory; import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.resolution.ArtifactResolutionException; import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.aether.transfer.ArtifactNotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class MavenStatusCommand -{ +public class MavenStatusCommand { /** * In order to verify artifacts can be downloaded from the remote repositories we want to resolve an actual * artifact. The Apache Maven artifact was chosen as it eventually, be it by proxy, mirror or directly, will be * gathered from the central repository. The version is chosen arbitrarily since any listed should work. */ - public static final Artifact APACHE_MAVEN_ARTIFACT = new DefaultArtifact( - "org.apache.maven", - "apache-maven", - null, - "pom", - "3.8.6" - ); + public static final Artifact APACHE_MAVEN_ARTIFACT = + new DefaultArtifact("org.apache.maven", "apache-maven", null, "pom", "3.8.6"); + private final MavenExecutionRequestPopulator mavenExecutionRequestPopulator; private final ArtifactResolver artifactResolver; private final RemoteRepositoryConnectionVerifier remoteRepositoryConnectionVerifier; @@ -79,131 +73,109 @@ public class MavenStatusCommand private final PlexusContainer container; private final SessionScope sessionScope; - public MavenStatusCommand( final PlexusContainer container ) throws ComponentLookupException - { + public MavenStatusCommand(final PlexusContainer container) throws ComponentLookupException { this.container = container; - this.remoteRepositoryConnectionVerifier = new RemoteRepositoryConnectionVerifier( container ); - mavenExecutionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class ); - logger = LoggerFactory.getILoggerFactory().getLogger( MavenStatusCommand.class.getName() ); - artifactResolver = container.lookup( ArtifactResolver.class ); - defaultSessionFactory = container.lookup( DefaultSessionFactory.class ); - repoSession = container.lookup( DefaultRepositorySystemSessionFactory.class ); - sessionScope = container.lookup( SessionScope.class ); + this.remoteRepositoryConnectionVerifier = new RemoteRepositoryConnectionVerifier(container); + mavenExecutionRequestPopulator = container.lookup(MavenExecutionRequestPopulator.class); + logger = LoggerFactory.getILoggerFactory().getLogger(MavenStatusCommand.class.getName()); + artifactResolver = container.lookup(ArtifactResolver.class); + defaultSessionFactory = container.lookup(DefaultSessionFactory.class); + repoSession = container.lookup(DefaultRepositorySystemSessionFactory.class); + sessionScope = container.lookup(SessionScope.class); } - public List verify( CliRequest cliRequest ) - throws Exception - { + public List verify(CliRequest cliRequest) throws Exception { // Populate the cliRequest with defaults and user settings final MavenExecutionRequest mavenExecutionRequest = - mavenExecutionRequestPopulator.populateDefaults( cliRequest.request ); + mavenExecutionRequestPopulator.populateDefaults(cliRequest.request); final ArtifactRepository localRepository = cliRequest.getRequest().getLocalRepository(); final List localRepositoryIssues = - verifyLocalRepository( Paths.get( URI.create( localRepository.getUrl() ) ) ); + verifyLocalRepository(Paths.get(URI.create(localRepository.getUrl()))); final List remoteRepositoryIssues = verifyRemoteRepositoryConnections( - cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest ); - final List artifactResolutionIssues = verifyArtifactResolution( mavenExecutionRequest ); + cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest); + final List artifactResolutionIssues = verifyArtifactResolution(mavenExecutionRequest); // Collect all issues into a single list - return Stream.of( localRepositoryIssues, remoteRepositoryIssues, artifactResolutionIssues ) - .flatMap( Collection::stream ) - .collect( Collectors.toList() ); + return Stream.of(localRepositoryIssues, remoteRepositoryIssues, artifactResolutionIssues) + .flatMap(Collection::stream) + .collect(Collectors.toList()); } private List verifyRemoteRepositoryConnections( - final List remoteRepositories, - final MavenExecutionRequest mavenExecutionRequest - ) { + final List remoteRepositories, final MavenExecutionRequest mavenExecutionRequest) { final List issues = new ArrayList<>(); - for ( ArtifactRepository remoteRepository : remoteRepositories ) - { - final RepositorySystemSession repositorySession = repoSession.newRepositorySession( mavenExecutionRequest ); - remoteRepositoryConnectionVerifier.verifyConnectionToRemoteRepository( repositorySession, remoteRepository ) - .ifPresent( issues::add ); + for (ArtifactRepository remoteRepository : remoteRepositories) { + final RepositorySystemSession repositorySession = repoSession.newRepositorySession(mavenExecutionRequest); + remoteRepositoryConnectionVerifier + .verifyConnectionToRemoteRepository(repositorySession, remoteRepository) + .ifPresent(issues::add); } return issues; } - private List verifyArtifactResolution( final MavenExecutionRequest mavenExecutionRequest ) - { - final Session session = this.defaultSessionFactory.getSession( - new MavenSession( - container, - repoSession.newRepositorySession( mavenExecutionRequest ), - mavenExecutionRequest, - new DefaultMavenExecutionResult() - ) - ); + private List verifyArtifactResolution(final MavenExecutionRequest mavenExecutionRequest) { + final Session session = this.defaultSessionFactory.getSession(new MavenSession( + container, + repoSession.newRepositorySession(mavenExecutionRequest), + mavenExecutionRequest, + new DefaultMavenExecutionResult())); sessionScope.enter(); - try - { - sessionScope.seed( DefaultSession.class, (DefaultSession) session ); + try { + sessionScope.seed(DefaultSession.class, (DefaultSession) session); - ArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate( session, APACHE_MAVEN_ARTIFACT ); - ArtifactResolverResult resolverResult = artifactResolver.resolve( session, - Collections.singleton( artifactCoordinate ) ); + ArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(session, APACHE_MAVEN_ARTIFACT); + ArtifactResolverResult resolverResult = + artifactResolver.resolve(session, Collections.singleton(artifactCoordinate)); - resolverResult.getArtifacts().forEach( ( key, value ) -> - logger.debug( "Successfully resolved {} to {}", key.toString(), value.toString() ) - ); + resolverResult + .getArtifacts() + .forEach((key, value) -> + logger.debug("Successfully resolved {} to {}", key.toString(), value.toString())); return Collections.emptyList(); - } - catch ( ArtifactResolverException are ) - { - return extractIssuesFromArtifactResolverException( are ); - } - finally - { + } catch (ArtifactResolverException are) { + return extractIssuesFromArtifactResolverException(are); + } finally { sessionScope.exit(); - logger.info( "Artifact resolution check completed" ); + logger.info("Artifact resolution check completed"); } } - private List extractIssuesFromArtifactResolverException( final Exception exception ) - { + private List extractIssuesFromArtifactResolverException(final Exception exception) { final boolean isArtifactResolutionException = exception.getCause() instanceof ArtifactResolutionException; - if ( isArtifactResolutionException ) - { - final ArtifactResolutionException are = ( ArtifactResolutionException ) exception.getCause(); + if (isArtifactResolutionException) { + final ArtifactResolutionException are = (ArtifactResolutionException) exception.getCause(); return are.getResults().stream() - .map( ArtifactResult::getExceptions ) - .flatMap( List::stream ) - .map( ArtifactNotFoundException.class::cast ) - .map( Throwable::getMessage ) - .collect( Collectors.toList() ); - } - else - { - return Collections.singletonList( exception.getMessage() ); + .map(ArtifactResult::getExceptions) + .flatMap(List::stream) + .map(ArtifactNotFoundException.class::cast) + .map(Throwable::getMessage) + .collect(Collectors.toList()); + } else { + return Collections.singletonList(exception.getMessage()); } } - private List verifyLocalRepository( final Path localRepositoryPath ) - { + private List verifyLocalRepository(final Path localRepositoryPath) { final List issues = new ArrayList<>(); - if ( !Files.isDirectory( localRepositoryPath ) ) - { - issues.add( "Local repository is not a directory." ); + if (!Files.isDirectory(localRepositoryPath)) { + issues.add("Local repository is not a directory."); } - if ( !Files.isReadable( localRepositoryPath ) ) - { - issues.add( "No read permissions on local repository." ); + if (!Files.isReadable(localRepositoryPath)) { + issues.add("No read permissions on local repository."); } - if ( !Files.isWritable( localRepositoryPath ) ) - { - issues.add( "No write permissions on local repository." ); + if (!Files.isWritable(localRepositoryPath)) { + issues.add("No write permissions on local repository."); } return issues; } } - diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java index 16d825d6ee99..9bdbd5ed5f5f 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java @@ -1,5 +1,26 @@ +/* + * 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.cli; +import java.net.URI; +import java.util.Optional; + import org.apache.commons.lang3.StringUtils; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.repository.ArtifactRepository; @@ -15,9 +36,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.net.URI; -import java.util.Optional; - /** * Helper class to verify connection to a remote repository. */ @@ -26,90 +44,83 @@ public class RemoteRepositoryConnectionVerifier { private final Logger logger; private final TransporterProvider transporterProvider; - public RemoteRepositoryConnectionVerifier( final PlexusContainer container ) throws ComponentLookupException - { - this.logger = LoggerFactory.getILoggerFactory().getLogger( RemoteRepositoryConnectionVerifier.class.getName() ); + public RemoteRepositoryConnectionVerifier(final PlexusContainer container) throws ComponentLookupException { + this.logger = LoggerFactory.getILoggerFactory().getLogger(RemoteRepositoryConnectionVerifier.class.getName()); this.transporterProvider = container.lookup(TransporterProvider.class); } - private boolean isCentralOrMirrorOfCentral( final RemoteRepository remoteRepository ) { - return "central".equals( remoteRepository.getId() ) || - remoteRepository.getMirroredRepositories().stream() - .map( RemoteRepository::getId ) - .anyMatch( "central"::equals ); + private boolean isCentralOrMirrorOfCentral(final RemoteRepository remoteRepository) { + return "central".equals(remoteRepository.getId()) + || remoteRepository.getMirroredRepositories().stream() + .map(RemoteRepository::getId) + .anyMatch("central"::equals); } - public Optional verifyConnectionToRemoteRepository( final RepositorySystemSession session, - final ArtifactRepository artifactRepository ) - { - final RemoteRepository repository = RepositoryUtils.toRepo( artifactRepository ); + public Optional verifyConnectionToRemoteRepository( + final RepositorySystemSession session, final ArtifactRepository artifactRepository) { + final RemoteRepository repository = RepositoryUtils.toRepo(artifactRepository); final String artifactPath; - if ( isCentralOrMirrorOfCentral( repository ) ) { + if (isCentralOrMirrorOfCentral(repository)) { // We can be sure the Apache Maven artifact should be resolvable. - artifactPath = artifactRepository.getLayout().pathOf( RepositoryUtils.toArtifact( APACHE_MAVEN_ARTIFACT ) ); + artifactPath = artifactRepository.getLayout().pathOf(RepositoryUtils.toArtifact(APACHE_MAVEN_ARTIFACT)); } else { // We cannot be sure about any artifact that lives here. artifactPath = "/"; } try { - final Transporter transporter = transporterProvider.newTransporter( session, repository ); - final Optional maybeIssue = verifyConnectionUsingTransport( transporter, repository, artifactPath ); + final Transporter transporter = transporterProvider.newTransporter(session, repository); + final Optional maybeIssue = verifyConnectionUsingTransport(transporter, repository, artifactPath); - if ( !maybeIssue.isPresent() ) { - logger.info( "Connection check for {} [{}] completed", repository.getId(), repository.getUrl() ); + if (!maybeIssue.isPresent()) { + logger.info("Connection check for {} [{}] completed", repository.getId(), repository.getUrl()); } return maybeIssue; - } catch ( final NoTransporterException nte ) { + } catch (final NoTransporterException nte) { final String message = String.format( "There is no compatible transport for remote repository %s with location %s", - repository.getId(), - repository.getUrl() - ); - return Optional.of( message ); + repository.getId(), repository.getUrl()); + return Optional.of(message); } } private Optional verifyConnectionUsingTransport( - final Transporter transporter, - final RemoteRepository remoteRepository, - final String artifactPath - ) { + final Transporter transporter, final RemoteRepository remoteRepository, final String artifactPath) { try { - final GetTask task = new GetTask( URI.create( artifactPath ) ); - transporter.get( task ); + final GetTask task = new GetTask(URI.create(artifactPath)); + transporter.get(task); return Optional.empty(); - } catch ( final Exception e ) { - return classifyException( remoteRepository, e ); + } catch (final Exception e) { + return classifyException(remoteRepository, e); } } - private Optional classifyException( final RemoteRepository remoteRepository, final Exception e ) { + private Optional classifyException(final RemoteRepository remoteRepository, final Exception e) { final String message = e.getMessage(); final String repositoryUrl = remoteRepository.getUrl(); - final boolean resourceMissing = StringUtils.contains( message, "resource missing" ); + final boolean resourceMissing = StringUtils.contains(message, "resource missing"); - if ( isCentralOrMirrorOfCentral( remoteRepository ) && resourceMissing ) { - final String issue = String.format( "Connection to %s possible, but expected artifact %s cannot be resolved", - repositoryUrl, APACHE_MAVEN_ARTIFACT ); - return Optional.of( issue ); + if (isCentralOrMirrorOfCentral(remoteRepository) && resourceMissing) { + final String issue = String.format( + "Connection to %s possible, but expected artifact %s cannot be resolved", + repositoryUrl, APACHE_MAVEN_ARTIFACT); + return Optional.of(issue); - } else if ( resourceMissing ) { + } else if (resourceMissing) { // We tried to resolve the artifact from a repository that does not necessarily host it. - logger.warn( "Connection to {} possible, but artifact {} not found", repositoryUrl, APACHE_MAVEN_ARTIFACT ); + logger.warn("Connection to {} possible, but artifact {} not found", repositoryUrl, APACHE_MAVEN_ARTIFACT); return Optional.empty(); - } else if ( StringUtils.contains( message, "authentication failed" ) ) { - final String issue = String.format( "Connection to %s possible, but authentication failed", repositoryUrl ); + } else if (StringUtils.contains(message, "authentication failed")) { + final String issue = String.format("Connection to %s possible, but authentication failed", repositoryUrl); return Optional.of(issue); - } - logger.error( "Error connecting to repository {} [{}]", remoteRepository.getId(), repositoryUrl, e ); - return Optional.of( "Unknown issue: " + e.getMessage() ); + logger.error("Error connecting to repository {} [{}]", remoteRepository.getId(), repositoryUrl, e); + return Optional.of("Unknown issue: " + e.getMessage()); } } From 7afb18e62426c2618e02a33c96c6488ee5354493 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 26 Jan 2023 16:16:50 +0100 Subject: [PATCH 16/43] [MNG-6869] Add todo to fix local repository issue --- maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index c3b71f3cee30..213a88bd463f 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -1241,6 +1241,8 @@ private MavenExecutionRequest populateRequest(CliRequest cliRequest, MavenExecut performProjectActivation(commandLine, request.getProjectActivation()); performProfileActivation(commandLine, request.getProfileActivation()); + // TODO: With --status we download to a newly created temp directory to ensure the artifact is not available, + // TODO: but we then validate that temp directory and not the actual artifact directory final String localRepositoryPath = determineLocalRepositoryPath(cliRequest); if (localRepositoryPath != null) { request.setLocalRepositoryPath(localRepositoryPath); From ca4cb330b1f6a44bb3db4539d54cb30254095d01 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 26 Jan 2023 16:16:49 +0100 Subject: [PATCH 17/43] [MNG-6869] Narrow declaration of thrown exception --- .../src/main/java/org/apache/maven/cli/MavenStatusCommand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index cfcd700891f3..d9403a0beef0 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -38,6 +38,7 @@ import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequestPopulator; +import org.apache.maven.execution.MavenExecutionRequestPopulationException; import org.apache.maven.execution.MavenSession; import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; import org.apache.maven.internal.impl.DefaultArtifactCoordinate; @@ -84,7 +85,7 @@ public MavenStatusCommand(final PlexusContainer container) throws ComponentLooku sessionScope = container.lookup(SessionScope.class); } - public List verify(CliRequest cliRequest) throws Exception { + public List verify(CliRequest cliRequest) throws MavenExecutionRequestPopulationException { // Populate the cliRequest with defaults and user settings final MavenExecutionRequest mavenExecutionRequest = mavenExecutionRequestPopulator.populateDefaults(cliRequest.request); From 0764fd0e1c08bc1510b3863c84741d24023f2f68 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 26 Jan 2023 16:17:29 +0100 Subject: [PATCH 18/43] [MNG-6869] Refine detection of possible connection issues --- .../RemoteRepositoryConnectionVerifier.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java index 9bdbd5ed5f5f..c83dc5ec3f7e 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java @@ -67,7 +67,7 @@ public Optional verifyConnectionToRemoteRepository( artifactPath = artifactRepository.getLayout().pathOf(RepositoryUtils.toArtifact(APACHE_MAVEN_ARTIFACT)); } else { // We cannot be sure about any artifact that lives here. - artifactPath = "/"; + artifactPath = ""; } try { @@ -100,27 +100,31 @@ private Optional verifyConnectionUsingTransport( private Optional classifyException(final RemoteRepository remoteRepository, final Exception e) { final String message = e.getMessage(); + final String repositoryId = remoteRepository.getId(); final String repositoryUrl = remoteRepository.getUrl(); + final String repository = String.format("%s [%s]", repositoryId, repositoryUrl); - final boolean resourceMissing = StringUtils.contains(message, "resource missing"); + final boolean notFound = StringUtils.contains(message, "status code: 404"); + final boolean unauthorized = StringUtils.contains(message, "status code: 401"); + final boolean forbidden = StringUtils.contains(message, "status code: 403"); - if (isCentralOrMirrorOfCentral(remoteRepository) && resourceMissing) { + if (isCentralOrMirrorOfCentral(remoteRepository) && notFound) { final String issue = String.format( "Connection to %s possible, but expected artifact %s cannot be resolved", - repositoryUrl, APACHE_MAVEN_ARTIFACT); + repository, APACHE_MAVEN_ARTIFACT); return Optional.of(issue); - } else if (resourceMissing) { + } else if (notFound) { // We tried to resolve the artifact from a repository that does not necessarily host it. - logger.warn("Connection to {} possible, but artifact {} not found", repositoryUrl, APACHE_MAVEN_ARTIFACT); + logger.warn("Connection to {} possible, but artifact {} not found", repository, APACHE_MAVEN_ARTIFACT); return Optional.empty(); - } else if (StringUtils.contains(message, "authentication failed")) { - final String issue = String.format("Connection to %s possible, but authentication failed", repositoryUrl); + } else if (unauthorized || forbidden) { + final String issue = String.format("Connection to %s possible, but access denied", repository); return Optional.of(issue); } - logger.error("Error connecting to repository {} [{}]", remoteRepository.getId(), repositoryUrl, e); + logger.error("Error connecting to repository {}", repository, e); return Optional.of("Unknown issue: " + e.getMessage()); } } From 30c96490adf05e2276ff0af84316c041e73e1728 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 9 Feb 2023 10:20:50 +0100 Subject: [PATCH 19/43] [MNG-6869] Use local repository correctly --- .../java/org/apache/maven/cli/MavenCli.java | 25 ++++---------- .../apache/maven/cli/MavenStatusCommand.java | 34 ++++++++++++++----- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 213a88bd463f..f787f3d29abb 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -409,7 +409,7 @@ private void status(CliRequest cliRequest) throws Exception { slf4jLoggerFactory = LoggerFactory.getILoggerFactory(); if (cliRequest.commandLine.hasOption(CLIManager.INSTALLATION_STATUS)) { MavenStatusCommand mavenStatusCommand = new MavenStatusCommand(plexusContainer); - final List mavenStatusIssues = mavenStatusCommand.verify(cliRequest); + final List mavenStatusIssues = mavenStatusCommand.verify(cliRequest.getRequest()); if (!mavenStatusIssues.isEmpty()) { for (String issue : mavenStatusIssues) { slf4jLogger.error(issue); @@ -1241,9 +1241,7 @@ private MavenExecutionRequest populateRequest(CliRequest cliRequest, MavenExecut performProjectActivation(commandLine, request.getProjectActivation()); performProfileActivation(commandLine, request.getProfileActivation()); - // TODO: With --status we download to a newly created temp directory to ensure the artifact is not available, - // TODO: but we then validate that temp directory and not the actual artifact directory - final String localRepositoryPath = determineLocalRepositoryPath(cliRequest); + final String localRepositoryPath = determineLocalRepositoryPath(request); if (localRepositoryPath != null) { request.setLocalRepositoryPath(localRepositoryPath); } @@ -1274,21 +1272,10 @@ private MavenExecutionRequest populateRequest(CliRequest cliRequest, MavenExecut return request; } - private String determineLocalRepositoryPath(final CliRequest cliRequest) { - final MavenExecutionRequest request = cliRequest.getRequest(); - if (cliRequest.commandLine.hasOption(CLIManager.INSTALLATION_STATUS)) { - try { - return Files.createTempDirectory("mvn-status").toAbsolutePath().toString(); - } catch (IOException ioe) { - final Logger logger = slf4jLoggerFactory.getLogger(getClass().getName()); - logger.debug("Could not create temporary local repository", ioe); - logger.warn("Artifact resolution test is less accurate as it may user earlier resolution results."); - } - } else { - String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); - if (userDefinedLocalRepo != null) { - return userDefinedLocalRepo; - } + private String determineLocalRepositoryPath(final MavenExecutionRequest request) { + String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY); + if (userDefinedLocalRepo != null) { + return userDefinedLocalRepo; } // TODO Investigate why this can also be a Java system property and not just a Maven user property like diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index d9403a0beef0..96346f5979df 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -18,6 +18,7 @@ */ package org.apache.maven.cli; +import java.io.File; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; @@ -35,10 +36,11 @@ import org.apache.maven.api.services.ArtifactResolverException; import org.apache.maven.api.services.ArtifactResolverResult; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; -import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenExecutionRequestPopulationException; +import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenSession; import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; import org.apache.maven.internal.impl.DefaultArtifactCoordinate; @@ -70,6 +72,7 @@ public class MavenStatusCommand { private final RemoteRepositoryConnectionVerifier remoteRepositoryConnectionVerifier; private final DefaultSessionFactory defaultSessionFactory; private final DefaultRepositorySystemSessionFactory repoSession; + private final MavenRepositorySystem repositorySystem; private final Logger logger; private final PlexusContainer container; private final SessionScope sessionScope; @@ -83,19 +86,22 @@ public MavenStatusCommand(final PlexusContainer container) throws ComponentLooku defaultSessionFactory = container.lookup(DefaultSessionFactory.class); repoSession = container.lookup(DefaultRepositorySystemSessionFactory.class); sessionScope = container.lookup(SessionScope.class); + repositorySystem = container.lookup(MavenRepositorySystem.class); } - public List verify(CliRequest cliRequest) throws MavenExecutionRequestPopulationException { - // Populate the cliRequest with defaults and user settings - final MavenExecutionRequest mavenExecutionRequest = - mavenExecutionRequestPopulator.populateDefaults(cliRequest.request); + public List verify(MavenExecutionRequest cliRequest) throws MavenExecutionRequestPopulationException { + final MavenExecutionRequest mavenExecutionRequest = mavenExecutionRequestPopulator.populateDefaults(cliRequest); - final ArtifactRepository localRepository = cliRequest.getRequest().getLocalRepository(); + final ArtifactRepository localRepository = cliRequest.getLocalRepository(); final List localRepositoryIssues = verifyLocalRepository(Paths.get(URI.create(localRepository.getUrl()))); - final List remoteRepositoryIssues = verifyRemoteRepositoryConnections( - cliRequest.getRequest().getRemoteRepositories(), mavenExecutionRequest); + + // We overwrite the local repository with a temporary folder to avoid using a cached version of the artifact. + setTemporaryLocalRepositoryPathOnRequest(cliRequest); + + final List remoteRepositoryIssues = + verifyRemoteRepositoryConnections(cliRequest.getRemoteRepositories(), mavenExecutionRequest); final List artifactResolutionIssues = verifyArtifactResolution(mavenExecutionRequest); // Collect all issues into a single list @@ -104,6 +110,18 @@ public List verify(CliRequest cliRequest) throws MavenExecutionRequestPo .collect(Collectors.toList()); } + private void setTemporaryLocalRepositoryPathOnRequest(MavenExecutionRequest request) { + try { + final String path = + Files.createTempDirectory("mvn-status").toAbsolutePath().toString(); + request.setLocalRepositoryPath(path); + request.setLocalRepository(repositorySystem.createLocalRepository(request, new File(path))); + } catch (Exception ex) { + logger.debug("Could not create temporary local repository", ex); + logger.warn("Artifact resolution test is less accurate as it may use earlier resolution results."); + } + } + private List verifyRemoteRepositoryConnections( final List remoteRepositories, final MavenExecutionRequest mavenExecutionRequest) { final List issues = new ArrayList<>(); From d134358283d948b5fce771b5cc96290c2398701c Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 9 Feb 2023 11:43:35 +0100 Subject: [PATCH 20/43] [MNG-6869] Clean up temp file after usage --- .../apache/maven/cli/MavenStatusCommand.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 96346f5979df..ab786ebfd509 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -19,6 +19,7 @@ package org.apache.maven.cli; import java.io.File; +import java.io.IOException; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; @@ -26,6 +27,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -67,6 +69,8 @@ public class MavenStatusCommand { public static final Artifact APACHE_MAVEN_ARTIFACT = new DefaultArtifact("org.apache.maven", "apache-maven", null, "pom", "3.8.6"); + private String tempLocalRepository; + private final MavenExecutionRequestPopulator mavenExecutionRequestPopulator; private final ArtifactResolver artifactResolver; private final RemoteRepositoryConnectionVerifier remoteRepositoryConnectionVerifier; @@ -104,18 +108,33 @@ public List verify(MavenExecutionRequest cliRequest) throws MavenExecuti verifyRemoteRepositoryConnections(cliRequest.getRemoteRepositories(), mavenExecutionRequest); final List artifactResolutionIssues = verifyArtifactResolution(mavenExecutionRequest); + cleanupTempFiles(); + // Collect all issues into a single list return Stream.of(localRepositoryIssues, remoteRepositoryIssues, artifactResolutionIssues) .flatMap(Collection::stream) .collect(Collectors.toList()); } + private void cleanupTempFiles() { + if (tempLocalRepository != null) { + try { + Files.walk(new File(tempLocalRepository).toPath()) + .sorted(Comparator.reverseOrder()) // Sort in reverse order so that directories are deleted last + .map(Path::toFile) + .forEach(File::delete); + } catch (IOException ioe) { + logger.debug("Failed to delete temporary local repository", ioe); + } + } + } + private void setTemporaryLocalRepositoryPathOnRequest(MavenExecutionRequest request) { try { - final String path = + tempLocalRepository = Files.createTempDirectory("mvn-status").toAbsolutePath().toString(); - request.setLocalRepositoryPath(path); - request.setLocalRepository(repositorySystem.createLocalRepository(request, new File(path))); + request.setLocalRepositoryPath(tempLocalRepository); + request.setLocalRepository(repositorySystem.createLocalRepository(request, new File(tempLocalRepository))); } catch (Exception ex) { logger.debug("Could not create temporary local repository", ex); logger.warn("Artifact resolution test is less accurate as it may use earlier resolution results."); From 6ba97e69111c8a0c40d9b67d303d49105a8baf41 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 11:51:51 +0100 Subject: [PATCH 21/43] [MNG-6869] Include local repository path in issue text --- .../main/java/org/apache/maven/cli/MavenStatusCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index ab786ebfd509..f2a589e2f52d 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -203,15 +203,15 @@ private List verifyLocalRepository(final Path localRepositoryPath) { final List issues = new ArrayList<>(); if (!Files.isDirectory(localRepositoryPath)) { - issues.add("Local repository is not a directory."); + issues.add(String.format("Local repository path %s is not a directory.", localRepositoryPath)); } if (!Files.isReadable(localRepositoryPath)) { - issues.add("No read permissions on local repository."); + issues.add(String.format("No read permissions on local repository %s.", localRepositoryPath)); } if (!Files.isWritable(localRepositoryPath)) { - issues.add("No write permissions on local repository."); + issues.add(String.format("No write permissions on local repository %s.", localRepositoryPath)); } return issues; From 79338ae556c6690c0eb06d0bd65211f3de897224 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 11:52:08 +0100 Subject: [PATCH 22/43] [MNG-6869] Mention local repo check has been completed --- .../src/main/java/org/apache/maven/cli/MavenStatusCommand.java | 1 + 1 file changed, 1 insertion(+) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index f2a589e2f52d..84a6112e584e 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -214,6 +214,7 @@ private List verifyLocalRepository(final Path localRepositoryPath) { issues.add(String.format("No write permissions on local repository %s.", localRepositoryPath)); } + logger.info("Local repository setup check completed"); return issues; } } From b470aca0e3218dad1ecc1f42cd9ee492f59f4c80 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 11:59:24 +0100 Subject: [PATCH 23/43] [MNG-6869] Output detected issues prefixed with a number --- .../src/main/java/org/apache/maven/cli/MavenCli.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index f787f3d29abb..e0ddf7259e84 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -41,6 +41,7 @@ import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.IntStream; import java.util.stream.Stream; import com.google.inject.AbstractModule; @@ -409,11 +410,11 @@ private void status(CliRequest cliRequest) throws Exception { slf4jLoggerFactory = LoggerFactory.getILoggerFactory(); if (cliRequest.commandLine.hasOption(CLIManager.INSTALLATION_STATUS)) { MavenStatusCommand mavenStatusCommand = new MavenStatusCommand(plexusContainer); - final List mavenStatusIssues = mavenStatusCommand.verify(cliRequest.getRequest()); - if (!mavenStatusIssues.isEmpty()) { - for (String issue : mavenStatusIssues) { - slf4jLogger.error(issue); - } + final List issues = mavenStatusCommand.verify(cliRequest.getRequest()); + if (!issues.isEmpty()) { + slf4jLogger.info(""); + slf4jLogger.error("The following issues where found"); + IntStream.range(0, issues.size()).forEach(i -> slf4jLogger.error("{}. {}", i + 1, issues.get(i))); throw new ExitException(1); } From 8629a8a4e82bb664fd83aebf9e5fb38e22add2db Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 13:48:52 +0100 Subject: [PATCH 24/43] [MNG-6869] Properly close streeam --- .../main/java/org/apache/maven/cli/MavenStatusCommand.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 84a6112e584e..aff7b18b0645 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -118,9 +118,8 @@ public List verify(MavenExecutionRequest cliRequest) throws MavenExecuti private void cleanupTempFiles() { if (tempLocalRepository != null) { - try { - Files.walk(new File(tempLocalRepository).toPath()) - .sorted(Comparator.reverseOrder()) // Sort in reverse order so that directories are deleted last + try(Stream files = Files.walk(new File(tempLocalRepository).toPath())) { + files.sorted(Comparator.reverseOrder()) // Sort in reverse order so that directories are deleted last .map(Path::toFile) .forEach(File::delete); } catch (IOException ioe) { From 7fcc3804cf5514d2f7182da6cf2983150ee569ea Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 13:51:29 +0100 Subject: [PATCH 25/43] [MNG-6869] Make logger a static constant --- .../main/java/org/apache/maven/cli/MavenStatusCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index aff7b18b0645..9450a6823d88 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -61,6 +61,8 @@ import org.slf4j.LoggerFactory; public class MavenStatusCommand { + private static final Logger logger = LoggerFactory.getLogger(MavenStatusCommand.class); + /** * In order to verify artifacts can be downloaded from the remote repositories we want to resolve an actual * artifact. The Apache Maven artifact was chosen as it eventually, be it by proxy, mirror or directly, will be @@ -77,7 +79,6 @@ public class MavenStatusCommand { private final DefaultSessionFactory defaultSessionFactory; private final DefaultRepositorySystemSessionFactory repoSession; private final MavenRepositorySystem repositorySystem; - private final Logger logger; private final PlexusContainer container; private final SessionScope sessionScope; @@ -85,7 +86,6 @@ public MavenStatusCommand(final PlexusContainer container) throws ComponentLooku this.container = container; this.remoteRepositoryConnectionVerifier = new RemoteRepositoryConnectionVerifier(container); mavenExecutionRequestPopulator = container.lookup(MavenExecutionRequestPopulator.class); - logger = LoggerFactory.getILoggerFactory().getLogger(MavenStatusCommand.class.getName()); artifactResolver = container.lookup(ArtifactResolver.class); defaultSessionFactory = container.lookup(DefaultSessionFactory.class); repoSession = container.lookup(DefaultRepositorySystemSessionFactory.class); From 2b01442e0934847c3d3671f821f8c190a0c02d12 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 13:52:49 +0100 Subject: [PATCH 26/43] [MNG-6869] Make it explicit we're populating instance variables --- .../org/apache/maven/cli/MavenStatusCommand.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 9450a6823d88..690876330c6d 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -85,12 +85,12 @@ public class MavenStatusCommand { public MavenStatusCommand(final PlexusContainer container) throws ComponentLookupException { this.container = container; this.remoteRepositoryConnectionVerifier = new RemoteRepositoryConnectionVerifier(container); - mavenExecutionRequestPopulator = container.lookup(MavenExecutionRequestPopulator.class); - artifactResolver = container.lookup(ArtifactResolver.class); - defaultSessionFactory = container.lookup(DefaultSessionFactory.class); - repoSession = container.lookup(DefaultRepositorySystemSessionFactory.class); - sessionScope = container.lookup(SessionScope.class); - repositorySystem = container.lookup(MavenRepositorySystem.class); + this.mavenExecutionRequestPopulator = container.lookup(MavenExecutionRequestPopulator.class); + this.artifactResolver = container.lookup(ArtifactResolver.class); + this.defaultSessionFactory = container.lookup(DefaultSessionFactory.class); + this.repoSession = container.lookup(DefaultRepositorySystemSessionFactory.class); + this.sessionScope = container.lookup(SessionScope.class); + this.repositorySystem = container.lookup(MavenRepositorySystem.class); } public List verify(MavenExecutionRequest cliRequest) throws MavenExecutionRequestPopulationException { From 95c52f25a08d34e2cf0601eafa9a2b516340da4b Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 13:53:09 +0100 Subject: [PATCH 27/43] [MNG-6869] Reorder instance variables --- .../src/main/java/org/apache/maven/cli/MavenStatusCommand.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 690876330c6d..90528fabf3af 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -71,8 +71,6 @@ public class MavenStatusCommand { public static final Artifact APACHE_MAVEN_ARTIFACT = new DefaultArtifact("org.apache.maven", "apache-maven", null, "pom", "3.8.6"); - private String tempLocalRepository; - private final MavenExecutionRequestPopulator mavenExecutionRequestPopulator; private final ArtifactResolver artifactResolver; private final RemoteRepositoryConnectionVerifier remoteRepositoryConnectionVerifier; @@ -81,6 +79,7 @@ public class MavenStatusCommand { private final MavenRepositorySystem repositorySystem; private final PlexusContainer container; private final SessionScope sessionScope; + private String tempLocalRepository; public MavenStatusCommand(final PlexusContainer container) throws ComponentLookupException { this.container = container; From d0f3b29f70e03e2534eaafcb8fb44675b080ff1f Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 13:54:05 +0100 Subject: [PATCH 28/43] [MNG-6869] Mark method arguments as final --- .../main/java/org/apache/maven/cli/MavenStatusCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 90528fabf3af..a5abd8221303 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -92,7 +92,7 @@ public MavenStatusCommand(final PlexusContainer container) throws ComponentLooku this.repositorySystem = container.lookup(MavenRepositorySystem.class); } - public List verify(MavenExecutionRequest cliRequest) throws MavenExecutionRequestPopulationException { + public List verify(final MavenExecutionRequest cliRequest) throws MavenExecutionRequestPopulationException { final MavenExecutionRequest mavenExecutionRequest = mavenExecutionRequestPopulator.populateDefaults(cliRequest); final ArtifactRepository localRepository = cliRequest.getLocalRepository(); @@ -127,7 +127,7 @@ private void cleanupTempFiles() { } } - private void setTemporaryLocalRepositoryPathOnRequest(MavenExecutionRequest request) { + private void setTemporaryLocalRepositoryPathOnRequest(final MavenExecutionRequest request) { try { tempLocalRepository = Files.createTempDirectory("mvn-status").toAbsolutePath().toString(); From 58e2f460a52cd3206d4e2dc6c59f6530c155fc75 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 13:59:26 +0100 Subject: [PATCH 29/43] [MNG-6869] Store temporary local repo as Path --- .../java/org/apache/maven/cli/MavenStatusCommand.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index a5abd8221303..909c982310f2 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -79,7 +79,7 @@ public class MavenStatusCommand { private final MavenRepositorySystem repositorySystem; private final PlexusContainer container; private final SessionScope sessionScope; - private String tempLocalRepository; + private Path tempLocalRepository; public MavenStatusCommand(final PlexusContainer container) throws ComponentLookupException { this.container = container; @@ -117,7 +117,7 @@ public List verify(final MavenExecutionRequest cliRequest) throws MavenE private void cleanupTempFiles() { if (tempLocalRepository != null) { - try(Stream files = Files.walk(new File(tempLocalRepository).toPath())) { + try (final Stream files = Files.walk(tempLocalRepository)) { files.sorted(Comparator.reverseOrder()) // Sort in reverse order so that directories are deleted last .map(Path::toFile) .forEach(File::delete); @@ -129,10 +129,9 @@ private void cleanupTempFiles() { private void setTemporaryLocalRepositoryPathOnRequest(final MavenExecutionRequest request) { try { - tempLocalRepository = - Files.createTempDirectory("mvn-status").toAbsolutePath().toString(); - request.setLocalRepositoryPath(tempLocalRepository); - request.setLocalRepository(repositorySystem.createLocalRepository(request, new File(tempLocalRepository))); + tempLocalRepository = Files.createTempDirectory("mvn-status").toAbsolutePath(); + request.setLocalRepositoryPath(tempLocalRepository.toString()); + request.setLocalRepository(repositorySystem.createLocalRepository(request, tempLocalRepository.toFile())); } catch (Exception ex) { logger.debug("Could not create temporary local repository", ex); logger.warn("Artifact resolution test is less accurate as it may use earlier resolution results."); From f67f7c3e0329316b16b4d6e51632c26f55cd4fda Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 14:17:46 +0100 Subject: [PATCH 30/43] [MNG-6869] Rename logger to LOGGER --- .../org/apache/maven/cli/MavenStatusCommand.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 909c982310f2..412cc05f22ce 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -61,7 +61,7 @@ import org.slf4j.LoggerFactory; public class MavenStatusCommand { - private static final Logger logger = LoggerFactory.getLogger(MavenStatusCommand.class); + private static final Logger LOGGER = LoggerFactory.getLogger(MavenStatusCommand.class); /** * In order to verify artifacts can be downloaded from the remote repositories we want to resolve an actual @@ -122,7 +122,7 @@ private void cleanupTempFiles() { .map(Path::toFile) .forEach(File::delete); } catch (IOException ioe) { - logger.debug("Failed to delete temporary local repository", ioe); + LOGGER.debug("Failed to delete temporary local repository", ioe); } } } @@ -133,8 +133,8 @@ private void setTemporaryLocalRepositoryPathOnRequest(final MavenExecutionReques request.setLocalRepositoryPath(tempLocalRepository.toString()); request.setLocalRepository(repositorySystem.createLocalRepository(request, tempLocalRepository.toFile())); } catch (Exception ex) { - logger.debug("Could not create temporary local repository", ex); - logger.warn("Artifact resolution test is less accurate as it may use earlier resolution results."); + LOGGER.debug("Could not create temporary local repository", ex); + LOGGER.warn("Artifact resolution test is less accurate as it may use earlier resolution results."); } } @@ -170,14 +170,14 @@ private List verifyArtifactResolution(final MavenExecutionRequest mavenE resolverResult .getArtifacts() .forEach((key, value) -> - logger.debug("Successfully resolved {} to {}", key.toString(), value.toString())); + LOGGER.debug("Successfully resolved {} to {}", key.toString(), value.toString())); return Collections.emptyList(); } catch (ArtifactResolverException are) { return extractIssuesFromArtifactResolverException(are); } finally { sessionScope.exit(); - logger.info("Artifact resolution check completed"); + LOGGER.info("Artifact resolution check completed"); } } @@ -211,7 +211,7 @@ private List verifyLocalRepository(final Path localRepositoryPath) { issues.add(String.format("No write permissions on local repository %s.", localRepositoryPath)); } - logger.info("Local repository setup check completed"); + LOGGER.info("Local repository setup check completed"); return issues; } } From 27a7e0aa790b81dbb5998b5df09059a0d3191cb7 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 14:20:30 +0100 Subject: [PATCH 31/43] [MNG-6869] Checkstyle: redundant modifier --- .../src/main/java/org/apache/maven/cli/MavenStatusCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 412cc05f22ce..b566d0ef7059 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -117,7 +117,7 @@ public List verify(final MavenExecutionRequest cliRequest) throws MavenE private void cleanupTempFiles() { if (tempLocalRepository != null) { - try (final Stream files = Files.walk(tempLocalRepository)) { + try (Stream files = Files.walk(tempLocalRepository)) { files.sorted(Comparator.reverseOrder()) // Sort in reverse order so that directories are deleted last .map(Path::toFile) .forEach(File::delete); From d2416a21811da2f45b03e18de757d5ac6aed2de5 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 9 Feb 2023 19:51:00 +0100 Subject: [PATCH 32/43] [MNG-6869] Minor review points --- .../java/org/apache/maven/cli/MavenStatusCommand.java | 11 +++++------ .../maven/cli/RemoteRepositoryConnectionVerifier.java | 7 +++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index b566d0ef7059..f39994033057 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -100,7 +100,7 @@ public List verify(final MavenExecutionRequest cliRequest) throws MavenE final List localRepositoryIssues = verifyLocalRepository(Paths.get(URI.create(localRepository.getUrl()))); - // We overwrite the local repository with a temporary folder to avoid using a cached version of the artifact. + // We overwrite the local repository with a temporary directory to avoid using a cached version of the artifact. setTemporaryLocalRepositoryPathOnRequest(cliRequest); final List remoteRepositoryIssues = @@ -169,8 +169,7 @@ private List verifyArtifactResolution(final MavenExecutionRequest mavenE resolverResult .getArtifacts() - .forEach((key, value) -> - LOGGER.debug("Successfully resolved {} to {}", key.toString(), value.toString())); + .forEach((key, value) -> LOGGER.debug("Successfully resolved {} to {}", key, value)); return Collections.emptyList(); } catch (ArtifactResolverException are) { @@ -200,15 +199,15 @@ private List verifyLocalRepository(final Path localRepositoryPath) { final List issues = new ArrayList<>(); if (!Files.isDirectory(localRepositoryPath)) { - issues.add(String.format("Local repository path %s is not a directory.", localRepositoryPath)); + issues.add(String.format("Local repository path '%s' is not a directory.", localRepositoryPath)); } if (!Files.isReadable(localRepositoryPath)) { - issues.add(String.format("No read permissions on local repository %s.", localRepositoryPath)); + issues.add(String.format("No read permissions on local repository '%s'.", localRepositoryPath)); } if (!Files.isWritable(localRepositoryPath)) { - issues.add(String.format("No write permissions on local repository %s.", localRepositoryPath)); + issues.add(String.format("No write permissions on local repository '%s'.", localRepositoryPath)); } LOGGER.info("Local repository setup check completed"); diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java index c83dc5ec3f7e..a14909272a54 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java @@ -75,13 +75,16 @@ public Optional verifyConnectionToRemoteRepository( final Optional maybeIssue = verifyConnectionUsingTransport(transporter, repository, artifactPath); if (!maybeIssue.isPresent()) { - logger.info("Connection check for {} [{}] completed", repository.getId(), repository.getUrl()); + logger.info( + "Connection check for repository '{}' at '{}' completed", + repository.getId(), + repository.getUrl()); } return maybeIssue; } catch (final NoTransporterException nte) { final String message = String.format( - "There is no compatible transport for remote repository %s with location %s", + "There is no compatible transport for remote repository '%s' with location '%s'", repository.getId(), repository.getUrl()); return Optional.of(message); } From 2a9ce5e4849196b3aa7d3e80334963b59822e0db Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 23 Feb 2023 12:14:09 +0100 Subject: [PATCH 33/43] [MNG-6869] Remove commented code --- .../src/main/java/org/apache/maven/cli/MavenCli.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index e0ddf7259e84..a581084edd1c 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -674,11 +674,6 @@ protected void configure() { defaultRepositorySystemSessionFactory = container.lookup(DefaultRepositorySystemSessionFactory.class); defaultSessionFactory = container.lookup(DefaultSessionFactory.class); mavenRepositorySystem = container.lookup(MavenRepositorySystem.class); - // - // private DefaultSessionFactory defaultSessionFactory; - // - // private MavenRepositorySystem mavenRepositorySystem; - // private DefaultRepositorySystemSessionFactory defaultRepositorySystemSessionFactory; plexusContainer = container; From ed191ad471103ae3c8ba988eacc54038198f5e63 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 23 Feb 2023 12:20:37 +0100 Subject: [PATCH 34/43] [MNG-6869] Use exception classification of Transporter --- .../RemoteRepositoryConnectionVerifier.java | 44 +++++++------------ 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java index a14909272a54..09f9c0b3d3c6 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java @@ -21,7 +21,6 @@ import java.net.URI; import java.util.Optional; -import org.apache.commons.lang3.StringUtils; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.repository.ArtifactRepository; import org.codehaus.plexus.PlexusContainer; @@ -72,16 +71,16 @@ public Optional verifyConnectionToRemoteRepository( try { final Transporter transporter = transporterProvider.newTransporter(session, repository); - final Optional maybeIssue = verifyConnectionUsingTransport(transporter, repository, artifactPath); + final Optional issue = verifyConnectionUsingTransport(transporter, repository, artifactPath); - if (!maybeIssue.isPresent()) { + if (!issue.isPresent()) { logger.info( "Connection check for repository '{}' at '{}' completed", repository.getId(), repository.getUrl()); } - return maybeIssue; + return issue; } catch (final NoTransporterException nte) { final String message = String.format( "There is no compatible transport for remote repository '%s' with location '%s'", @@ -94,40 +93,27 @@ private Optional verifyConnectionUsingTransport( final Transporter transporter, final RemoteRepository remoteRepository, final String artifactPath) { try { final GetTask task = new GetTask(URI.create(artifactPath)); + // We could connect, but uncertain to what. Could be the repository, could be a valid web page. transporter.get(task); return Optional.empty(); } catch (final Exception e) { - return classifyException(remoteRepository, e); + int errorOrArtifactNotFound = transporter.classify(e); + if (Transporter.ERROR_NOT_FOUND == errorOrArtifactNotFound) { + // No-op since we could connect to the repository + // However we do not know what should or shouldn't be present + return Optional.empty(); + } + // In this case it is Transporter.ERROR_OTHER + return formatException(remoteRepository, e); } } - private Optional classifyException(final RemoteRepository remoteRepository, final Exception e) { - final String message = e.getMessage(); + private Optional formatException(final RemoteRepository remoteRepository, final Exception e) { final String repositoryId = remoteRepository.getId(); final String repositoryUrl = remoteRepository.getUrl(); final String repository = String.format("%s [%s]", repositoryId, repositoryUrl); - final boolean notFound = StringUtils.contains(message, "status code: 404"); - final boolean unauthorized = StringUtils.contains(message, "status code: 401"); - final boolean forbidden = StringUtils.contains(message, "status code: 403"); - - if (isCentralOrMirrorOfCentral(remoteRepository) && notFound) { - final String issue = String.format( - "Connection to %s possible, but expected artifact %s cannot be resolved", - repository, APACHE_MAVEN_ARTIFACT); - return Optional.of(issue); - - } else if (notFound) { - // We tried to resolve the artifact from a repository that does not necessarily host it. - logger.warn("Connection to {} possible, but artifact {} not found", repository, APACHE_MAVEN_ARTIFACT); - return Optional.empty(); - - } else if (unauthorized || forbidden) { - final String issue = String.format("Connection to %s possible, but access denied", repository); - return Optional.of(issue); - } - - logger.error("Error connecting to repository {}", repository, e); - return Optional.of("Unknown issue: " + e.getMessage()); + final String issue = String.format("Connection to %s not possible. Cause: %s", repository, e.getMessage()); + return Optional.of(issue); } } From 6adddbd1d7850ce5b4278c5f59c739f5817088ac Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 23 Feb 2023 13:26:01 +0100 Subject: [PATCH 35/43] [MNG-6869] Make formatException signature non-optional --- .../maven/cli/RemoteRepositoryConnectionVerifier.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java index 09f9c0b3d3c6..a27e9b638532 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java @@ -104,16 +104,15 @@ private Optional verifyConnectionUsingTransport( return Optional.empty(); } // In this case it is Transporter.ERROR_OTHER - return formatException(remoteRepository, e); + return Optional.of(formatException(remoteRepository, e)); } } - private Optional formatException(final RemoteRepository remoteRepository, final Exception e) { + private String formatException(final RemoteRepository remoteRepository, final Exception e) { final String repositoryId = remoteRepository.getId(); final String repositoryUrl = remoteRepository.getUrl(); final String repository = String.format("%s [%s]", repositoryId, repositoryUrl); - final String issue = String.format("Connection to %s not possible. Cause: %s", repository, e.getMessage()); - return Optional.of(issue); + return String.format("Connection to %s not possible. Cause: %s", repository, e.getMessage()); } } From 9443a2ac3ab7602d612c9f4a3cdb160f6af94fd5 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 23 Feb 2023 13:35:03 +0100 Subject: [PATCH 36/43] [MNG-6869] Remove unnecessary comment --- .../src/main/java/org/apache/maven/cli/MavenCli.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index a581084edd1c..080287caf99d 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -887,8 +887,7 @@ private void repository(CliRequest cliRequest) throws Exception { } private int execute(CliRequest cliRequest) throws MavenExecutionRequestPopulationException { - MavenExecutionRequest request = - executionRequestPopulator.populateDefaults(cliRequest.request); // Populate request + MavenExecutionRequest request = executionRequestPopulator.populateDefaults(cliRequest.request); if (cliRequest.request.getRepositoryCache() == null) { cliRequest.request.setRepositoryCache(new DefaultRepositoryCache()); From 41177b3d4ddfb4adc78acadcdbe68823fb0bdc98 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Thu, 23 Feb 2023 13:50:02 +0100 Subject: [PATCH 37/43] [MNG-6869] Remove unused DI fields --- .../main/java/org/apache/maven/cli/MavenCli.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 080287caf99d..47a7caffb5d3 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -53,7 +53,6 @@ import org.apache.maven.BuildAbort; import org.apache.maven.InternalErrorException; import org.apache.maven.Maven; -import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.building.FileSource; import org.apache.maven.building.Problem; import org.apache.maven.building.Source; @@ -86,8 +85,6 @@ import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule; import org.apache.maven.extension.internal.CoreExports; import org.apache.maven.extension.internal.CoreExtensionEntry; -import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; -import org.apache.maven.internal.impl.DefaultSessionFactory; import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.logwrapper.LogLevelRecorder; import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory; @@ -182,12 +179,6 @@ public class MavenCli { private PlexusContainer plexusContainer; - private DefaultSessionFactory defaultSessionFactory; - - private MavenRepositorySystem mavenRepositorySystem; - - private DefaultRepositorySystemSessionFactory defaultRepositorySystemSessionFactory; - private static final Pattern NEXT_LINE = Pattern.compile("\r?\n"); public MavenCli() { @@ -671,10 +662,6 @@ protected void configure() { dispatcher = (DefaultSecDispatcher) container.lookup(SecDispatcher.class, "maven"); - defaultRepositorySystemSessionFactory = container.lookup(DefaultRepositorySystemSessionFactory.class); - defaultSessionFactory = container.lookup(DefaultSessionFactory.class); - mavenRepositorySystem = container.lookup(MavenRepositorySystem.class); - plexusContainer = container; return container; From fc2e7f719cc3388d221546853bbff0182a13b9a0 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 23 Feb 2023 12:06:18 +0100 Subject: [PATCH 38/43] [MNG-6869] Make no assumptions about the existence of Maven Central --- .../RemoteRepositoryConnectionVerifier.java | 29 ++++--------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java index a27e9b638532..5d683154bb28 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java @@ -26,7 +26,6 @@ import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.spi.connector.transport.GetTask; import org.eclipse.aether.spi.connector.transport.Transporter; @@ -39,7 +38,6 @@ * Helper class to verify connection to a remote repository. */ public class RemoteRepositoryConnectionVerifier { - private static final Artifact APACHE_MAVEN_ARTIFACT = MavenStatusCommand.APACHE_MAVEN_ARTIFACT; private final Logger logger; private final TransporterProvider transporterProvider; @@ -48,30 +46,13 @@ public RemoteRepositoryConnectionVerifier(final PlexusContainer container) throw this.transporterProvider = container.lookup(TransporterProvider.class); } - private boolean isCentralOrMirrorOfCentral(final RemoteRepository remoteRepository) { - return "central".equals(remoteRepository.getId()) - || remoteRepository.getMirroredRepositories().stream() - .map(RemoteRepository::getId) - .anyMatch("central"::equals); - } - public Optional verifyConnectionToRemoteRepository( final RepositorySystemSession session, final ArtifactRepository artifactRepository) { final RemoteRepository repository = RepositoryUtils.toRepo(artifactRepository); - final String artifactPath; - - if (isCentralOrMirrorOfCentral(repository)) { - // We can be sure the Apache Maven artifact should be resolvable. - artifactPath = artifactRepository.getLayout().pathOf(RepositoryUtils.toArtifact(APACHE_MAVEN_ARTIFACT)); - } else { - // We cannot be sure about any artifact that lives here. - artifactPath = ""; - } - try { final Transporter transporter = transporterProvider.newTransporter(session, repository); - final Optional issue = verifyConnectionUsingTransport(transporter, repository, artifactPath); + final Optional issue = verifyConnectionUsingTransport(transporter, repository); if (!issue.isPresent()) { logger.info( @@ -90,14 +71,14 @@ public Optional verifyConnectionToRemoteRepository( } private Optional verifyConnectionUsingTransport( - final Transporter transporter, final RemoteRepository remoteRepository, final String artifactPath) { + final Transporter transporter, final RemoteRepository remoteRepository) { try { - final GetTask task = new GetTask(URI.create(artifactPath)); - // We could connect, but uncertain to what. Could be the repository, could be a valid web page. + final GetTask task = new GetTask(URI.create("")); transporter.get(task); + // We could connect, but uncertain to what. Could be the repository, could be a valid web page. return Optional.empty(); } catch (final Exception e) { - int errorOrArtifactNotFound = transporter.classify(e); + final int errorOrArtifactNotFound = transporter.classify(e); if (Transporter.ERROR_NOT_FOUND == errorOrArtifactNotFound) { // No-op since we could connect to the repository // However we do not know what should or shouldn't be present From 2114cdaf1ca890876793b9b89ae77e84795c3500 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 23 Feb 2023 12:06:36 +0100 Subject: [PATCH 39/43] [MNG-6869] Simplify --- .../cli/RemoteRepositoryConnectionVerifier.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java index 5d683154bb28..9935b08de1a6 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/RemoteRepositoryConnectionVerifier.java @@ -52,16 +52,7 @@ public Optional verifyConnectionToRemoteRepository( try { final Transporter transporter = transporterProvider.newTransporter(session, repository); - final Optional issue = verifyConnectionUsingTransport(transporter, repository); - - if (!issue.isPresent()) { - logger.info( - "Connection check for repository '{}' at '{}' completed", - repository.getId(), - repository.getUrl()); - } - - return issue; + return verifyConnectionUsingTransport(transporter, repository); } catch (final NoTransporterException nte) { final String message = String.format( "There is no compatible transport for remote repository '%s' with location '%s'", @@ -76,6 +67,10 @@ private Optional verifyConnectionUsingTransport( final GetTask task = new GetTask(URI.create("")); transporter.get(task); // We could connect, but uncertain to what. Could be the repository, could be a valid web page. + logger.info( + "Connection check for repository '{}' at '{}' completed", + remoteRepository.getId(), + remoteRepository.getUrl()); return Optional.empty(); } catch (final Exception e) { final int errorOrArtifactNotFound = transporter.classify(e); From 853819ce7aaebb1b86d6b1dbde1388dc5bbc3614 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 23 Feb 2023 14:31:38 +0100 Subject: [PATCH 40/43] [MNG-6869] Prevent possible ClassCastException This could happen when the artifact resolution did not work due to other reasons than a non-existing artifact - such as a non-existing hostname. --- .../src/main/java/org/apache/maven/cli/MavenStatusCommand.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index f39994033057..5cd91c4bacaf 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -56,7 +56,6 @@ import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.resolution.ArtifactResolutionException; import org.eclipse.aether.resolution.ArtifactResult; -import org.eclipse.aether.transfer.ArtifactNotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -187,7 +186,6 @@ private List extractIssuesFromArtifactResolverException(final Exception return are.getResults().stream() .map(ArtifactResult::getExceptions) .flatMap(List::stream) - .map(ArtifactNotFoundException.class::cast) .map(Throwable::getMessage) .collect(Collectors.toList()); } else { From f39aec28c39a164fdefa263874593c5bc12f0af0 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Wed, 10 May 2023 15:31:23 +0200 Subject: [PATCH 41/43] [MNG-6869] Revert unrelated change --- .../maven/internal/impl/DefaultArtifactCoordinate.java | 5 ++--- .../main/java/org/apache/maven/cli/MavenStatusCommand.java | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java index 030a28e5399b..d76b161766ce 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java @@ -21,7 +21,6 @@ import java.util.Objects; import org.apache.maven.api.ArtifactCoordinate; -import org.apache.maven.api.Session; import org.apache.maven.api.VersionRange; import org.apache.maven.api.annotations.Nonnull; @@ -31,11 +30,11 @@ * A wrapper class around a maven resolver artifact. */ public class DefaultArtifactCoordinate implements ArtifactCoordinate { - private final @Nonnull Session session; + private final @Nonnull AbstractSession session; private final @Nonnull org.eclipse.aether.artifact.Artifact coordinate; public DefaultArtifactCoordinate( - @Nonnull Session session, @Nonnull org.eclipse.aether.artifact.Artifact coordinate) { + @Nonnull AbstractSession session, @Nonnull org.eclipse.aether.artifact.Artifact coordinate) { this.session = nonNull(session, "session can not be null"); this.coordinate = nonNull(coordinate, "coordinate can not be null"); } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 5cd91c4bacaf..4a9d5828b282 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -162,7 +162,8 @@ private List verifyArtifactResolution(final MavenExecutionRequest mavenE try { sessionScope.seed(DefaultSession.class, (DefaultSession) session); - ArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(session, APACHE_MAVEN_ARTIFACT); + ArtifactCoordinate artifactCoordinate = + new DefaultArtifactCoordinate((DefaultSession) session, APACHE_MAVEN_ARTIFACT); ArtifactResolverResult resolverResult = artifactResolver.resolve(session, Collections.singleton(artifactCoordinate)); From eaf2421b34575c4672c242470c28454b9e6b5a3e Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Fri, 26 Apr 2024 13:41:05 +0200 Subject: [PATCH 42/43] [MNG-6869] Make it work with recent changes --- .../apache/maven/cli/MavenStatusCommand.java | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 493ede6c5d70..34eae910f52f 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -44,10 +44,10 @@ import org.apache.maven.execution.MavenExecutionRequestPopulationException; import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenSession; -import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; import org.apache.maven.internal.impl.DefaultArtifactCoordinate; -import org.apache.maven.internal.impl.DefaultSession; import org.apache.maven.internal.impl.DefaultSessionFactory; +import org.apache.maven.internal.impl.InternalMavenSession; +import org.apache.maven.resolver.RepositorySystemSessionFactory; import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; @@ -74,19 +74,17 @@ public class MavenStatusCommand { private final ArtifactResolver artifactResolver; private final RemoteRepositoryConnectionVerifier remoteRepositoryConnectionVerifier; private final DefaultSessionFactory defaultSessionFactory; - private final DefaultRepositorySystemSessionFactory repoSession; + private final RepositorySystemSessionFactory repoSession; private final MavenRepositorySystem repositorySystem; - private final PlexusContainer container; private final SessionScope sessionScope; private Path tempLocalRepository; public MavenStatusCommand(final PlexusContainer container) throws ComponentLookupException { - this.container = container; this.remoteRepositoryConnectionVerifier = new RemoteRepositoryConnectionVerifier(container); this.mavenExecutionRequestPopulator = container.lookup(MavenExecutionRequestPopulator.class); this.artifactResolver = container.lookup(ArtifactResolver.class); this.defaultSessionFactory = container.lookup(DefaultSessionFactory.class); - this.repoSession = container.lookup(DefaultRepositorySystemSessionFactory.class); + this.repoSession = container.lookup(RepositorySystemSessionFactory.class); this.sessionScope = container.lookup(SessionScope.class); this.repositorySystem = container.lookup(MavenRepositorySystem.class); } @@ -142,31 +140,34 @@ private List verifyRemoteRepositoryConnections( final List issues = new ArrayList<>(); for (ArtifactRepository remoteRepository : remoteRepositories) { - final RepositorySystemSession repositorySession = repoSession.newRepositorySession(mavenExecutionRequest); + final RepositorySystemSession.CloseableSession repositorySession = repoSession + .newRepositorySessionBuilder(mavenExecutionRequest) + .build(); remoteRepositoryConnectionVerifier .verifyConnectionToRemoteRepository(repositorySession, remoteRepository) .ifPresent(issues::add); + repositorySession.close(); } return issues; } private List verifyArtifactResolution(final MavenExecutionRequest mavenExecutionRequest) { - final Session session = this.defaultSessionFactory.newSession(new MavenSession( - container, - repoSession.newRepositorySession(mavenExecutionRequest), - mavenExecutionRequest, - new DefaultMavenExecutionResult())); - + RepositorySystemSession.CloseableSession repoSession = this.repoSession + .newRepositorySessionBuilder(mavenExecutionRequest) + .build(); + final Session session = this.defaultSessionFactory.newSession( + new MavenSession(repoSession, mavenExecutionRequest, new DefaultMavenExecutionResult())); + repoSession.close(); sessionScope.enter(); try { - sessionScope.seed(DefaultSession.class, (DefaultSession) session); + InternalMavenSession internalSession = InternalMavenSession.from(session); + sessionScope.seed(InternalMavenSession.class, internalSession); ArtifactCoordinate artifactCoordinate = - new DefaultArtifactCoordinate((DefaultSession) session, APACHE_MAVEN_ARTIFACT); + new DefaultArtifactCoordinate(internalSession, APACHE_MAVEN_ARTIFACT); ArtifactResolverResult resolverResult = artifactResolver.resolve(session, Collections.singleton(artifactCoordinate)); - resolverResult .getArtifacts() .forEach((key, value) -> LOGGER.debug("Successfully resolved {} to {}", key, value)); From 63006dff580236bbcbe09528594921e6cb33b9a6 Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Fri, 26 Apr 2024 14:05:31 +0200 Subject: [PATCH 43/43] [MNG-6869] Make use of try with resources --- .../apache/maven/cli/MavenStatusCommand.java | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java index 34eae910f52f..2b3cc88bc19d 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java @@ -47,6 +47,7 @@ import org.apache.maven.internal.impl.DefaultArtifactCoordinate; import org.apache.maven.internal.impl.DefaultSessionFactory; import org.apache.maven.internal.impl.InternalMavenSession; +import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.resolver.RepositorySystemSessionFactory; import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.PlexusContainer; @@ -140,32 +141,29 @@ private List verifyRemoteRepositoryConnections( final List issues = new ArrayList<>(); for (ArtifactRepository remoteRepository : remoteRepositories) { - final RepositorySystemSession.CloseableSession repositorySession = repoSession + try (RepositorySystemSession.CloseableSession repositorySession = repoSession .newRepositorySessionBuilder(mavenExecutionRequest) - .build(); - remoteRepositoryConnectionVerifier - .verifyConnectionToRemoteRepository(repositorySession, remoteRepository) - .ifPresent(issues::add); - repositorySession.close(); + .build()) { + remoteRepositoryConnectionVerifier + .verifyConnectionToRemoteRepository(repositorySession, remoteRepository) + .ifPresent(issues::add); + } } return issues; } private List verifyArtifactResolution(final MavenExecutionRequest mavenExecutionRequest) { - RepositorySystemSession.CloseableSession repoSession = this.repoSession + this.sessionScope.enter(); + try (RepositorySystemSession.CloseableSession repoSession = this.repoSession .newRepositorySessionBuilder(mavenExecutionRequest) - .build(); - final Session session = this.defaultSessionFactory.newSession( - new MavenSession(repoSession, mavenExecutionRequest, new DefaultMavenExecutionResult())); - repoSession.close(); - sessionScope.enter(); - try { + .build()) { + final Session session = this.defaultSessionFactory.newSession( + new MavenSession(repoSession, mavenExecutionRequest, new DefaultMavenExecutionResult())); InternalMavenSession internalSession = InternalMavenSession.from(session); sessionScope.seed(InternalMavenSession.class, internalSession); - ArtifactCoordinate artifactCoordinate = - new DefaultArtifactCoordinate(internalSession, APACHE_MAVEN_ARTIFACT); + new DefaultArtifactCoordinate(InternalSession.from(session), APACHE_MAVEN_ARTIFACT); ArtifactResolverResult resolverResult = artifactResolver.resolve(session, Collections.singleton(artifactCoordinate)); resolverResult @@ -176,7 +174,7 @@ private List verifyArtifactResolution(final MavenExecutionRequest mavenE } catch (ArtifactResolverException are) { return extractIssuesFromArtifactResolverException(are); } finally { - sessionScope.exit(); + this.sessionScope.exit(); LOGGER.info("Artifact resolution check completed"); } }