diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java index 88602e50ac..1937d75c72 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java @@ -48,6 +48,7 @@ import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ResolutionErrorHandler; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; import org.apache.maven.artifact.versioning.ArtifactVersion; @@ -801,6 +802,9 @@ public abstract class AbstractSurefireMojo @Component private ProviderDetector providerDetector; + @Component + private ResolutionErrorHandler resolutionErrorHandler; + private Toolchain toolchain; private int effectiveForkCount = -1; @@ -1001,6 +1005,7 @@ private void setupStuff() throws MojoFailureException getConsoleLogger(), getLocalRepository(), getRemoteRepositories(), getProjectRemoteRepositories(), + resolutionErrorHandler, getPluginName(), getSession().isOffline() ); @@ -2474,6 +2479,7 @@ private ForkNodeFactory getForkNodeFactory() @Nonnull private ForkConfiguration createForkConfiguration( @Nonnull Platform platform, @Nonnull ResolvePathResultWrapper resolvedJavaModularityResult ) + throws MojoExecutionException { File tmpDir = getSurefireTempDir(); @@ -2899,7 +2905,7 @@ private void showArray( T[] array, String setting ) } } - private Classpath getArtifactClasspath( Artifact surefireArtifact ) + private Classpath getArtifactClasspath( Artifact surefireArtifact ) throws MojoExecutionException { Classpath existing = classpathCache.getCachedClassPath( surefireArtifact.getArtifactId() ); if ( existing == null ) @@ -3154,7 +3160,7 @@ public List getJpmsArguments( @Nonnull ProviderRequirements forkRequir @Override @Nonnull - public Set getProviderClasspath() + public Set getProviderClasspath() throws MojoExecutionException { Artifact surefireArtifact = getBooterArtifact(); String version = surefireArtifact.getBaseVersion(); @@ -3191,7 +3197,7 @@ public List getJpmsArguments( @Nonnull ProviderRequirements forkRequir @Override @Nonnull - public Set getProviderClasspath() + public Set getProviderClasspath() throws MojoExecutionException { // add the JUnit provider as default - it doesn't require JUnit to be present, // since it supports POJO tests. @@ -3239,7 +3245,7 @@ public List getJpmsArguments( @Nonnull ProviderRequirements forkRequir @Override @Nonnull - public Set getProviderClasspath() + public Set getProviderClasspath() throws MojoExecutionException { String version = getBooterArtifact().getBaseVersion(); return surefireDependencyResolver.getProviderClasspath( "surefire-junit4", version ); @@ -3365,7 +3371,7 @@ private List getJpmsArgs() } private void addEngineByApi( String engineGroupId, String engineArtifactId, String engineVersion, - Map providerArtifacts ) + Map providerArtifacts ) throws MojoExecutionException { for ( Artifact dep : resolve( engineGroupId, engineArtifactId, engineVersion, null, "jar" ) ) { @@ -3380,7 +3386,7 @@ private void narrowDependencies( Map providerArtifacts, providerArtifacts.keySet().removeAll( testDependencies.keySet() ); } - private void alignProviderVersions( Map providerArtifacts ) + private void alignProviderVersions( Map providerArtifacts ) throws MojoExecutionException { String version = junitPlatformArtifact.getBaseVersion(); for ( Artifact launcherArtifact : resolve( PROVIDER_DEP_GID, PROVIDER_DEP_AID, version, null, "jar" ) ) @@ -3393,7 +3399,7 @@ private void alignProviderVersions( Map providerArtifacts ) } } - private Set resolve( String g, String a, String v, String c, String t ) + private Set resolve( String g, String a, String v, String c, String t ) throws MojoExecutionException { ArtifactHandler handler = junitPlatformArtifact.getArtifactHandler(); Artifact artifact = new DefaultArtifact( g, a, v, null, t, c, handler ); @@ -3471,7 +3477,7 @@ public List getJpmsArguments( @Nonnull ProviderRequirements forkRequir @Override @Nonnull - public Set getProviderClasspath() + public Set getProviderClasspath() throws MojoExecutionException { String version = getBooterArtifact().getBaseVersion(); return surefireDependencyResolver.getProviderClasspath( "surefire-junit47", version ); @@ -4082,6 +4088,11 @@ public void setTempDir( String tempDir ) this.tempDir = tempDir; } + public void setResolutionErrorHandler( ResolutionErrorHandler resolutionErrorHandler ) + { + this.resolutionErrorHandler = resolutionErrorHandler; + } + private static String getEffectiveForkMode( String forkMode ) { if ( "pertest".equalsIgnoreCase( forkMode ) ) diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java index 081fed2e3b..45de14dd75 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java @@ -32,8 +32,10 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.artifact.resolver.ResolutionErrorHandler; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; @@ -41,6 +43,7 @@ import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Dependency; import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.surefire.log.api.ConsoleLogger; import org.apache.maven.repository.RepositorySystem; @@ -87,8 +90,9 @@ final class SurefireDependencyResolver private final List projectRemoteRepositories; - private final String pluginName; + private final ResolutionErrorHandler resolutionErrorHandler; + private final String pluginName; private final boolean offline; @@ -96,6 +100,7 @@ final class SurefireDependencyResolver ArtifactRepository localRepository, List pluginRemoteRepositories, List projectRemoteRepositories, + ResolutionErrorHandler resolutionErrorHandler, String pluginName, boolean offline ) { this.repositorySystem = repositorySystem; @@ -103,6 +108,7 @@ final class SurefireDependencyResolver this.localRepository = localRepository; this.pluginRemoteRepositories = pluginRemoteRepositories; this.projectRemoteRepositories = projectRemoteRepositories; + this.resolutionErrorHandler = resolutionErrorHandler; this.pluginName = pluginName; this.offline = offline; } @@ -132,6 +138,7 @@ static boolean isWithinVersionSpec( @Nullable Artifact artifact, @Nonnull String } Map resolvePluginDependencies( Plugin plugin, Map pluginResolvedDependencies ) + throws MojoExecutionException { Map resolved = new LinkedHashMap<>(); Collection pluginDependencies = plugin.getDependencies(); @@ -153,28 +160,30 @@ Map resolvePluginDependencies( Plugin plugin, Map repositories, - ArtifactFilter filter ) + ArtifactFilter filter ) throws MojoExecutionException { ArtifactResolutionRequest request = new ArtifactResolutionRequest() .setOffline( offline ) @@ -184,11 +193,22 @@ private ArtifactResolutionResult resolveArtifact( Artifact artifact, List getProviderClasspath( String providerArtifactId, String providerVersion ) + throws MojoExecutionException { Dependency provider = toProviderDependency( providerArtifactId, providerVersion ); @@ -211,6 +231,7 @@ Set getProviderClasspath( String providerArtifactId, String providerVe @Nonnull Map getProviderClasspathAsMap( String providerArtifactId, String providerVersion ) + throws MojoExecutionException { return artifactMapByVersionlessId( getProviderClasspath( providerArtifactId, providerVersion ) ); } diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java index 8bcf947203..ec00a22a43 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java @@ -44,6 +44,7 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.artifact.resolver.DefaultResolutionErrorHandler; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; @@ -157,6 +158,7 @@ public void setupMojo() plugin.setVersion( mojoArtifact.getVersion() ); when( pluginDescriptor.getPlugin() ).thenReturn( plugin ); mojo.setPluginDescriptor( pluginDescriptor ); + mojo.setResolutionErrorHandler( new DefaultResolutionErrorHandler() ); } @Test diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java index 5593233067..5b9512267b 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java @@ -27,12 +27,15 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.artifact.resolver.DefaultResolutionErrorHandler; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Dependency; import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.surefire.SurefireDependencyResolver.RuntimeArtifactFilter; import org.apache.maven.plugin.surefire.log.api.ConsoleLogger; import org.apache.maven.repository.RepositorySystem; @@ -49,6 +52,7 @@ import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec; import static org.apache.maven.plugin.surefire.SurefireDependencyResolver.PROVIDER_GROUP_ID; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -108,7 +112,7 @@ public void shouldBeFailWithinRange() throws InvalidVersionSpecificationExceptio } @Test - public void testResolveArtifact() throws InvalidVersionSpecificationException + public void testResolveArtifact() throws InvalidVersionSpecificationException, MojoExecutionException { final Artifact provider = createArtifact( "surefire-junit-platform" ); RepositorySystem repositorySystem = mock( RepositorySystem.class ); @@ -152,7 +156,8 @@ public ArtifactResolutionResult answer( InvocationOnMock invocation ) } ); SurefireDependencyResolver surefireDependencyResolver = - new SurefireDependencyResolver( repositorySystem, null, null, null, null, null, false ); + new SurefireDependencyResolver( repositorySystem, null, null, null, null, + new DefaultResolutionErrorHandler(), null, false ); ArtifactResolutionResult actualResult = surefireDependencyResolver.resolvePluginArtifact( provider ); @@ -246,7 +251,8 @@ public Artifact answer( InvocationOnMock invocation ) ConsoleLogger log = mock( ConsoleLogger.class ); SurefireDependencyResolver surefireDependencyResolver = - new SurefireDependencyResolver( repositorySystem, log, null, null, null, null, false ); + new SurefireDependencyResolver( repositorySystem, log, null, null, null, + new DefaultResolutionErrorHandler(), null, false ); when( log.isDebugEnabled() ) .thenReturn( true ); @@ -275,6 +281,35 @@ public Artifact answer( InvocationOnMock invocation ) .isSameAs( ext ); } + @Test + public void testGetProviderClasspathShouldPropagateTheResolutionException() throws Exception + { + Artifact provider = createArtifact( "surefire-junit-platform" ); + provider.setFile( null ); + + Set providerArtifacts = new LinkedHashSet<>(); + providerArtifacts.add( provider ); + + ArtifactResolutionResult result = mock( ArtifactResolutionResult.class ); + when( result.getArtifacts() ).thenReturn( providerArtifacts ); + when( result.hasMetadataResolutionExceptions() ).thenReturn( true ); + ArtifactResolutionException resolutionException = + new ArtifactResolutionException( "failed to resolve", provider ); + when( result.getMetadataResolutionException( 0 ) ).thenReturn( resolutionException ); + + RepositorySystem repositorySystem = mock( RepositorySystem.class ); + when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) ).thenReturn( result ); + when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenReturn( provider ); + + SurefireDependencyResolver surefireDependencyResolver = + new SurefireDependencyResolver( repositorySystem, mock( ConsoleLogger.class ), null, null, null, + new DefaultResolutionErrorHandler(), null, false ); + + assertThatThrownBy( () -> surefireDependencyResolver.getProviderClasspath( "surefire-junit-platform", "1" ) ) + .isInstanceOf( MojoExecutionException.class ) + .hasCause( resolutionException ); + } + @Test public void testResolvePluginDependencies() throws Exception { @@ -306,7 +341,8 @@ public void testResolvePluginDependencies() throws Exception singletonMap( PROVIDER_GROUP_ID + ":surefire-shadefire", providerAsArtifact ); SurefireDependencyResolver surefireDependencyResolver = - new SurefireDependencyResolver( repositorySystem, null, null, null, null, null, false ); + new SurefireDependencyResolver( repositorySystem, null, null, null, null, + new DefaultResolutionErrorHandler(), null, false ); Map providers = surefireDependencyResolver.resolvePluginDependencies( plugin, pluginResolvedDependencies );