From dev-return-127742-archive-asf-public=cust-asf.ponee.io@maven.apache.org Fri Mar 1 19:36:16 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 6103C180676 for ; Fri, 1 Mar 2019 20:36:14 +0100 (CET) Received: (qmail 15874 invoked by uid 500); 1 Mar 2019 19:36:13 -0000 Mailing-List: contact dev-help@maven.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Maven Developers List" Reply-To: "Maven Developers List" Delivered-To: mailing list dev@maven.apache.org Received: (qmail 15771 invoked by uid 99); 1 Mar 2019 19:36:12 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Mar 2019 19:36:12 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 119B8C183D for ; Fri, 1 Mar 2019 19:36:12 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.798 X-Spam-Level: * X-Spam-Status: No, score=1.798 tagged_above=-999 required=6.31 tests=[DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=2, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=disabled Authentication-Results: spamd4-us-west.apache.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id YCXzwArLV0TE for ; Fri, 1 Mar 2019 19:36:05 +0000 (UTC) Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with ESMTPS id C209D60DD8 for ; Fri, 1 Mar 2019 19:36:04 +0000 (UTC) Received: by mail-lf1-f49.google.com with SMTP id j1so18831433lfb.10 for ; Fri, 01 Mar 2019 11:36:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=pKzLd2gM9wfkFtBdxsDBWyrfz/sEpjVLs0eGo+mNZR0=; b=kM/euE+FbfaFHqvUy+s2pYHFjBK9o7bFxiPPSf8J+gLgv1Zfx8Z8Z/7MG3Y8zDtQ30 4js+WrhkL5rYkGYBaTzwuxfrR3his1Rl9Bo3DnllediRA7Q2e79eNeo1MxgFmDxVt80A CCcm8EC8I5jDZ6xoB19/MpNTY+EO90ns6RLQ1wKwLRQGd2q6EvI4uamAX5nWk6+FzTED rCxcPtzIRfnnTA7AFUq3wdGFWR4Ab+nwRg5exdOhjQkp3wTXAq0PABkjS/HQ5v1UZwlU JhT6NmXwrjXgDNk7VEw4/DQHHyeLEMMgwijmrALD9gPGAck1RpyxjcqFb476lupHX6E9 O98A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=pKzLd2gM9wfkFtBdxsDBWyrfz/sEpjVLs0eGo+mNZR0=; b=jgiEaZjAXrV6Y/e44D+SouRjR4I3fJqb//KcYmGEm2mNEYQCB1twJVjKAxHW9KEDBr SAbUFqA+QoCtJPaE00F0iAshBOK6wGAeAhZgSMU/bKQz2GSGPNzA50/Og7XkFKBelKYF 1an4VYIW5hNY2gaVgrNU0DCNZltGNjpwLpKprW1/BFfG3ch4bJELnw1ofYW7lJRpjAMK ntNMBAPTD2eeQEe/tSS7X6baV57gBNkRztRbyTg9iegCtB6vRsJ7kPijLBqOsU+Giwbb wq9RS8Ov96LMBUpNn2F7dRXkCzPY3slonJrVr6qW/CzW68UwhZQUNIBnSKr909a5VxCs BImA== X-Gm-Message-State: APjAAAWUMNVC66ONyxH/GdOCOGy3QXpNSaMB6PkHGEZ7Ztd2TT6tH5F8 kgy0JxbRgpmkUQg6rHmYhs2sy61EGh9jgdU0oTGABg== X-Google-Smtp-Source: APXvYqza1nM5naudlQlPa0H6p5v7PcKs2YxB1cCNaCbtBvaNwtPwe4bVHQGhqV48Gjk+TKOhuaQ0TUBOZYKQ1uAvR5g= X-Received: by 2002:ac2:51c7:: with SMTP id u7mr2704586lfm.30.1551468962652; Fri, 01 Mar 2019 11:36:02 -0800 (PST) MIME-Version: 1.0 References: <155146752501.24386.2809107556729920333@gitbox.apache.org> In-Reply-To: <155146752501.24386.2809107556729920333@gitbox.apache.org> From: Enrico Olivelli Date: Fri, 1 Mar 2019 20:35:51 +0100 Message-ID: Subject: Re: [maven-surefire] branch master updated: [SUREFIRE-1585] Align JUnit Platform version at runtime To: Maven Developers List Content-Type: multipart/alternative; boundary="0000000000006626dc05830d845b" --0000000000006626dc05830d845b Content-Type: text/plain; charset="UTF-8" This is a great feature! Il ven 1 mar 2019, 20:12 ha scritto: > This is an automated email from the ASF dual-hosted git repository. > > tibordigana pushed a commit to branch master > in repository https://gitbox.apache.org/repos/asf/maven-surefire.git > > > The following commit(s) were added to refs/heads/master by this push: > new de50626 [SUREFIRE-1585] Align JUnit Platform version at runtime > de50626 is described below > > commit de506262225c43e43be4fd64cf25940e5a807aaa > Author: tibordigana > AuthorDate: Fri Feb 1 06:03:27 2019 +0100 > > [SUREFIRE-1585] Align JUnit Platform version at runtime > --- > maven-failsafe-plugin/pom.xml | 13 +- > maven-surefire-common/pom.xml | 23 +- > .../plugin/surefire/AbstractSurefireMojo.java | 352 ++++-- > .../apache/maven/plugin/surefire/ProviderInfo.java | 2 +- > .../surefire/SurefireDependencyResolver.java | 103 +- > .../maven/plugin/surefire/TestClassPath.java | 34 +- > .../AbstractSurefireMojoJava7PlusTest.java | 5 +- > .../plugin/surefire/AbstractSurefireMojoTest.java | 1271 > +++++++++++++++++++- > .../surefire/SurefireDependencyResolverTest.java | 8 +- > maven-surefire-plugin/pom.xml | 5 + > .../src/site/apt/examples/junit-platform.apt.vm | 110 +- > maven-surefire-report-plugin/pom.xml | 5 - > pom.xml | 39 +- > surefire-api/pom.xml | 4 +- > .../maven/surefire/its/JUnitPlatformEnginesIT.java | 8 +- > .../maven/surefire/its/jiras/Surefire1585IT.java | 54 + > .../resources/surefire-1585-junit4-vintage/pom.xml | 61 + > .../src/test/java/JUnit4Test.java | 26 +- > .../resources/surefire-1585-jupiter-api/pom.xml | 54 + > .../src/test/java/JupiterTest.java | 28 +- > surefire-providers/common-java5/pom.xml | 4 +- > surefire-report-parser/pom.xml | 4 +- > 22 files changed, 1970 insertions(+), 243 deletions(-) > > diff --git a/maven-failsafe-plugin/pom.xml b/maven-failsafe-plugin/pom.xml > index c947b54..31dcfbf 100644 > --- a/maven-failsafe-plugin/pom.xml > +++ b/maven-failsafe-plugin/pom.xml > @@ -60,6 +60,11 @@ > site-source > > > + org.apache.maven > + maven-core > + provided > + > + > org.apache.maven.plugin-tools > maven-plugin-annotations > provided > @@ -208,16 +213,16 @@ > > > > - > org.apache.maven.shared > - org.apache. > maven.surefire.shade.org.apache.maven.shared > + > org.apache.maven.shared.utils > + > org.apache.maven.surefire.shade.failsafe.org.apache.maven.shared.utils > > > org.apache.commons.io > > - > org.apache.maven.surefire.shade.org.apache.commons.io > + > org.apache.maven.surefire.shade.failsafe.org.apache.commons.io > > > > > org.apache.commons.lang3 > - org.apache. > maven.surefire.shade.org.apache.commons.lang3 > + > org.apache.maven.surefire.shade.failsafe.org.apache.commons.lang3 > > > > diff --git a/maven-surefire-common/pom.xml b/maven-surefire-common/pom.xml > index 57adfa9..770642e 100644 > --- a/maven-surefire-common/pom.xml > +++ b/maven-surefire-common/pom.xml > @@ -53,27 +53,12 @@ > provided > > > - org.apache.maven > - maven-plugin-api > - provided > - > - > org.apache.maven.plugin-tools > maven-plugin-annotations > provided > > > org.apache.maven > - maven-artifact > - provided > - > - > - org.apache.maven > - maven-model > - provided > - > - > - org.apache.maven > maven-toolchain > > > @@ -81,6 +66,10 @@ > maven-common-artifact-filters > > > + org.apache.maven.shared > + maven-artifact-transfer > + > + > org.codehaus.plexus > plexus-java > > @@ -165,8 +154,8 @@ > > > > - > org.apache.maven.shared > - > org.apache.maven.surefire.shade.common.org.apache.maven.shared > + > org.apache.maven.shared.utils > + > org.apache.maven.surefire.shade.common.org.apache.maven.shared.utils > > > org.apache.commons.io > > 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 7c76ef1..ba7f1e0 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 > @@ -21,8 +21,12 @@ package org.apache.maven.plugin.surefire; > */ > > import org.apache.maven.artifact.Artifact; > +import org.apache.maven.artifact.DefaultArtifact; > +import org.apache.maven.artifact.handler.ArtifactHandler; > import org.apache.maven.artifact.repository.ArtifactRepository; > +import org.apache.maven.model.Dependency; > import org.apache.maven.plugins.annotations.Component; > +import org.apache.maven.project.ProjectBuildingRequest; > import org.apache.maven.repository.RepositorySystem; > import org.apache.maven.artifact.resolver.filter.ArtifactFilter; > import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; > @@ -50,6 +54,7 @@ import > org.apache.maven.plugin.surefire.util.DirectoryScanner; > import org.apache.maven.plugins.annotations.Parameter; > import org.apache.maven.project.MavenProject; > import > org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter; > +import > org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; > import org.apache.maven.shared.utils.io.FileUtils; > import org.apache.maven.surefire.booter.ClassLoaderConfiguration; > import org.apache.maven.surefire.booter.Classpath; > @@ -90,6 +95,7 @@ import java.math.BigDecimal; > import java.nio.file.Files; > import java.nio.file.Paths; > import java.util.ArrayList; > +import java.util.Collection; > import java.util.Collections; > import java.util.Enumeration; > import java.util.HashMap; > @@ -112,6 +118,7 @@ import static java.util.Collections.singletonList; > import static java.util.Collections.singletonMap; > import static org.apache.commons.lang3.StringUtils.substringBeforeLast; > import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS; > +import static > org.apache.maven.artifact.ArtifactUtils.artifactMapByVersionlessId; > import static > org.apache.maven.plugin.surefire.SurefireDependencyResolver.isWithinVersionSpec; > import static > org.apache.maven.plugin.surefire.util.DependencyScanner.filter; > import static > org.apache.maven.plugin.surefire.SurefireHelper.replaceThreadNumberPlaceholders; > @@ -478,15 +485,6 @@ public abstract class AbstractSurefireMojo > private String junitArtifactName; > > /** > - * Allows you to specify the name of the JUnit Platform artifact. > - * If not set, {@code org.junit.platform:junit-platform-engine} will > be used. > - * > - * @since 2.22.0 > - */ > - @Parameter( property = "junitPlatformArtifactName", defaultValue = > "org.junit.platform:junit-platform-engine" ) > - private String junitPlatformArtifactName; > - > - /** > * Allows you to specify the name of the TestNG artifact. If not set, > {@code org.testng:testng} will be used. > * > * @since 2.3.1 > @@ -663,6 +661,9 @@ public abstract class AbstractSurefireMojo > @Parameter( defaultValue = "${project.pluginArtifactRepositories}", > readonly = true, required = true ) > private List remoteRepositories; > > + @Parameter( defaultValue = "${project.remoteArtifactRepositories}", > required = true, readonly = true ) > + private List projectRemoteRepositories; > + > /** > * Flag to disable the generation of report files in xml format. > * > @@ -737,6 +738,9 @@ public abstract class AbstractSurefireMojo > @Component > private RepositorySystem repositorySystem; > > + @Component > + private DependencyResolver dependencyResolver; > + > private Artifact surefireBooterArtifact; > > private Toolchain toolchain; > @@ -798,7 +802,7 @@ public abstract class AbstractSurefireMojo > */ > protected Artifact getMojoArtifact() > { > - return pluginDescriptor.getPluginArtifact(); > + return getPluginDescriptor().getPluginArtifact(); > } > > private String getDefaultExcludes() > @@ -806,7 +810,7 @@ public abstract class AbstractSurefireMojo > return "**/*$*"; > } > > - private SurefireDependencyResolver dependencyResolver; > + private SurefireDependencyResolver surefireDependencyResolver; > > private TestListResolver specificTests; > > @@ -842,6 +846,11 @@ public abstract class AbstractSurefireMojo > } > } > > + void setLogger( Logger logger ) > + { > + this.logger = logger; > + } > + > @Nonnull > protected final PluginConsoleLogger getConsoleLogger() > { > @@ -860,9 +869,22 @@ public abstract class AbstractSurefireMojo > > private void setupStuff() > { > - createDependencyResolver(); > - surefireBooterArtifact = getSurefireBooterArtifact(); > - toolchain = getToolchain(); > + surefireDependencyResolver = new SurefireDependencyResolver( > getRepositorySystem(), > + getConsoleLogger(), getLocalRepository(), > + getRemoteRepositories(), > + getProjectRemoteRepositories(), > + getPluginName(), getDependencyResolver() ); > + > + surefireBooterArtifact = getBooterArtifact(); > + if ( surefireBooterArtifact == null ) > + { > + throw new RuntimeException( "Unable to locate surefire-booter > in the list of plugin artifacts" ); > + } > + > + if ( getToolchainManager() != null ) > + { > + toolchain = > getToolchainManager().getToolchainFromBuildContext( "jdk", getSession() ); > + } > } > > @Nonnull > @@ -983,7 +1005,8 @@ public abstract class AbstractSurefireMojo > private void executeAfterPreconditionsChecked( @Nonnull > DefaultScanResult scanResult ) > throws MojoExecutionException, MojoFailureException > { > - List providers = createProviders(); > + TestClassPath testClasspath = generateTestClasspath(); > + List providers = createProviders( testClasspath ); > > RunResult current = noTestsRun(); > > @@ -992,7 +1015,7 @@ public abstract class AbstractSurefireMojo > { > try > { > - current = current.aggregate( executeProvider( provider, > scanResult ) ); > + current = current.aggregate( executeProvider( provider, > scanResult, testClasspath ) ); > } > catch ( SurefireBooterForkException | > SurefireExecutionException | TestSetFailedException e ) > { > @@ -1011,21 +1034,13 @@ public abstract class AbstractSurefireMojo > handleSummary( current, firstForkException ); > } > > - private void createDependencyResolver() > - { > - dependencyResolver = new SurefireDependencyResolver( > getRepositorySystem(), > - > getConsoleLogger(), getLocalRepository(), > - > getRemoteRepositories(), > - > getPluginName() ); > - } > - > - protected List createProviders() > + protected List createProviders( TestClassPath > testClasspath ) > throws MojoExecutionException > { > Artifact junitDepArtifact = getJunitDepArtifact(); > return new ProviderList( new DynamicProviderInfo( null ), > new TestNgProviderInfo( getTestNgArtifact() > ), > - new JUnitPlatformProviderInfo( > getJunitPlatformArtifact() ), > + new JUnitPlatformProviderInfo( > getJunitPlatformArtifact(), testClasspath ), > new JUnitCoreProviderInfo( > getJunitArtifact(), junitDepArtifact ), > new JUnit4ProviderInfo( getJunitArtifact(), > junitDepArtifact ), > new JUnit3ProviderInfo() ) > @@ -1117,7 +1132,8 @@ public abstract class AbstractSurefireMojo > } > > @Nonnull > - private RunResult executeProvider( @Nonnull ProviderInfo provider, > @Nonnull DefaultScanResult scanResult ) > + private RunResult executeProvider( @Nonnull ProviderInfo provider, > @Nonnull DefaultScanResult scanResult, > + @Nonnull TestClassPath > testClasspathWrapper ) > throws MojoExecutionException, MojoFailureException, > SurefireExecutionException, SurefireBooterForkException, > TestSetFailedException > { > @@ -1132,8 +1148,8 @@ public abstract class AbstractSurefireMojo > { > createCopyAndReplaceForkNumPlaceholder( effectiveProperties, > 1 ).copyToSystemProperties(); > > - InPluginVMSurefireStarter surefireStarter = > - createInprocessStarter( provider, > classLoaderConfiguration, runOrderParameters, scanResult, platform ); > + InPluginVMSurefireStarter surefireStarter = > createInprocessStarter( provider, classLoaderConfiguration, > + runOrderParameters, scanResult, platform, > testClasspathWrapper ); > return surefireStarter.runSuitesInProcess( scanResult ); > } > else > @@ -1149,7 +1165,8 @@ public abstract class AbstractSurefireMojo > try > { > forkStarter = createForkStarter( provider, > forkConfiguration, classLoaderConfiguration, > - > runOrderParameters, getConsoleLogger(), scanResult, platform ); > + > runOrderParameters, getConsoleLogger(), scanResult, platform, > + > testClasspathWrapper ); > > return forkStarter.run( effectiveProperties, scanResult ); > } > @@ -1214,16 +1231,14 @@ public abstract class AbstractSurefireMojo > this.repositorySystem = repositorySystem; > } > > - final Toolchain getToolchain() > + public DependencyResolver getDependencyResolver() > { > - Toolchain tc = null; > - > - if ( getToolchainManager() != null ) > - { > - tc = getToolchainManager().getToolchainFromBuildContext( > "jdk", getSession() ); > - } > + return dependencyResolver; > + } > > - return tc; > + public void setDependencyResolver( DependencyResolver > dependencyResolver ) > + { > + this.dependencyResolver = dependencyResolver; > } > > private boolean existsModuleDescriptor() > @@ -1688,7 +1703,7 @@ public abstract class AbstractSurefireMojo > return h; > } > > - public File getStatisticsFile( String configurationHash ) > + private File getStatisticsFile( String configurationHash ) > { > return new File( getBasedir(), ".surefire-" + configurationHash ); > } > @@ -1696,7 +1711,8 @@ public abstract class AbstractSurefireMojo > private StartupConfiguration createStartupConfiguration( @Nonnull > ProviderInfo provider, boolean isInprocess, > @Nonnull > ClassLoaderConfiguration classLoaderConfiguration, > @Nonnull > DefaultScanResult scanResult, > - @Nonnull > Platform platform ) > + @Nonnull > Platform platform, > + @Nonnull > TestClassPath testClasspathWrapper ) > throws MojoExecutionException > { > try > @@ -1714,11 +1730,12 @@ public abstract class AbstractSurefireMojo > .toString(); > > return newStartupConfigWithModularPath( > classLoaderConfiguration, providerArtifacts, providerName, > - getModuleDescriptor(), scanResult, javaHome ); > + getModuleDescriptor(), scanResult, javaHome, > testClasspathWrapper ); > } > else > { > - return newStartupConfigWithClasspath( > classLoaderConfiguration, providerArtifacts, providerName ); > + return newStartupConfigWithClasspath( > classLoaderConfiguration, providerArtifacts, providerName, > + testClasspathWrapper ); > } > } > catch ( IOException e ) > @@ -1729,13 +1746,10 @@ public abstract class AbstractSurefireMojo > > private StartupConfiguration newStartupConfigWithClasspath( > @Nonnull ClassLoaderConfiguration classLoaderConfiguration, > @Nonnull Set providerArtifacts, > - @Nonnull String providerName ) > + @Nonnull String providerName, @Nonnull TestClassPath > testClasspathWrapper ) > { > - TestClassPath testClasspathWrapper = generateTestClasspath(); > Classpath testClasspath = testClasspathWrapper.toClasspath(); > > - testClasspathWrapper.avoidArtifactDuplicates( providerArtifacts ); > - > Classpath providerClasspath = ClasspathCache.getCachedClassPath( > providerName ); > if ( providerClasspath == null ) > { > @@ -1769,8 +1783,8 @@ public abstract class AbstractSurefireMojo > boolean contains = false; > for ( Artifact providerArtifact : providerArtifacts ) > { > - if ( providerArtifact.getGroupId().equals( > inPluginArtifact.getGroupId() ) > - && providerArtifact.getArtifactId().equals( > inPluginArtifact.getArtifactId() ) ) > + if ( hasGroupArtifactId( providerArtifact.getGroupId(), > providerArtifact.getArtifactId(), > + inPluginArtifact ) ) > { > contains = true; > break; > @@ -1784,6 +1798,11 @@ public abstract class AbstractSurefireMojo > return result; > } > > + private static boolean hasGroupArtifactId( String groupId, String > artifactId, Artifact artifact ) > + { > + return groupId.equals( artifact.getGroupId() ) && > artifactId.equals( artifact.getArtifactId() ); > + } > + > private static Classpath createInProcClasspath( Classpath > providerClasspath, Set newArtifacts ) > { > Classpath inprocClasspath = providerClasspath.clone(); > @@ -1806,14 +1825,11 @@ public abstract class AbstractSurefireMojo > private StartupConfiguration newStartupConfigWithModularPath( > @Nonnull ClassLoaderConfiguration classLoaderConfiguration, > @Nonnull Set providerArtifacts, > @Nonnull String providerName, @Nonnull File moduleDescriptor, > @Nonnull DefaultScanResult scanResult, > - @Nonnull String javaHome ) > + @Nonnull String javaHome, @Nonnull TestClassPath > testClasspathWrapper ) > throws IOException > { > - TestClassPath testClasspathWrapper = generateTestClasspath(); > Classpath testClasspath = testClasspathWrapper.toClasspath(); > > - testClasspathWrapper.avoidArtifactDuplicates( providerArtifacts ); > - > Classpath providerClasspath = ClasspathCache.getCachedClassPath( > providerName ); > if ( providerClasspath == null ) > { > @@ -2123,14 +2139,19 @@ public abstract class AbstractSurefireMojo > return getProjectArtifactMap().get( "junit:junit-dep" ); > } > > - > private Artifact getJunitPlatformArtifact() > { > - Artifact artifact = getProjectArtifactMap().get( > getJunitPlatformArtifactName() ); > - Artifact projectArtifact = project.getArtifact(); > - String projectArtifactName = projectArtifact.getGroupId() + ":" + > projectArtifact.getArtifactId(); > + Artifact artifact = getProjectArtifactMap().get( > "org.junit.platform:junit-platform-commons" ); > + if ( artifact == null ) > + { > + artifact = getPluginArtifactMap().get( > "org.junit.platform:junit-platform-engine" ); > + } > > - if ( artifact == null && projectArtifactName.equals( > getJunitPlatformArtifactName() ) ) > + Artifact projectArtifact = project.getArtifact(); > + String projectGroupId = projectArtifact.getGroupId(); > + if ( artifact == null && ( "org.junit.platform".equals( > projectGroupId ) > + || "org.junit.jupiter".equals( projectGroupId ) > + || "org.junit.vintage".equals( projectGroupId ) ) ) > { > artifact = projectArtifact; > } > @@ -2141,11 +2162,12 @@ public abstract class AbstractSurefireMojo > private ForkStarter createForkStarter( @Nonnull ProviderInfo > provider, @Nonnull ForkConfiguration forkConfiguration, > @Nonnull > ClassLoaderConfiguration classLoaderConfiguration, > @Nonnull RunOrderParameters > runOrderParameters, @Nonnull ConsoleLogger log, > - @Nonnull DefaultScanResult > scanResult, @Nonnull Platform platform ) > + @Nonnull DefaultScanResult > scanResult, @Nonnull Platform platform, > + @Nonnull TestClassPath > testClasspathWrapper ) > throws MojoExecutionException, MojoFailureException > { > - StartupConfiguration startupConfiguration = > - createStartupConfiguration( provider, false, > classLoaderConfiguration, scanResult, platform ); > + StartupConfiguration startupConfiguration = > createStartupConfiguration( provider, false, > + classLoaderConfiguration, scanResult, platform, > testClasspathWrapper ); > String configChecksum = getConfigChecksum(); > StartupReportConfiguration startupReportConfiguration = > getStartupReportConfiguration( configChecksum, true ); > ProviderConfiguration providerConfiguration = > createProviderConfiguration( runOrderParameters ); > @@ -2157,11 +2179,12 @@ public abstract class AbstractSurefireMojo > @Nonnull > ClassLoaderConfiguration classLoaderConfig, > @Nonnull > RunOrderParameters runOrderParameters, > @Nonnull > DefaultScanResult scanResult, > - @Nonnull > Platform platform ) > + @Nonnull > Platform platform, > + @Nonnull > TestClassPath testClasspathWrapper ) > throws MojoExecutionException, MojoFailureException > { > - StartupConfiguration startupConfiguration = > - createStartupConfiguration( provider, true, > classLoaderConfig, scanResult, platform ); > + StartupConfiguration startupConfiguration = > createStartupConfiguration( provider, true, classLoaderConfig, > + scanResult, platform, testClasspathWrapper ); > String configChecksum = getConfigChecksum(); > StartupReportConfiguration startupReportConfiguration = > getStartupReportConfiguration( configChecksum, false ); > ProviderConfiguration providerConfiguration = > createProviderConfiguration( runOrderParameters ); > @@ -2353,16 +2376,6 @@ public abstract class AbstractSurefireMojo > return new JdkAttributes( jvmToUse, isBuiltInJava9AtLeast() ); > } > > - private Artifact getSurefireBooterArtifact() > - { > - Artifact artifact = getBooterArtifact(); > - if ( artifact == null ) > - { > - throw new RuntimeException( "Unable to locate surefire-booter > in the list of plugin artifacts" ); > - } > - return artifact; > - } > - > /** > * Where surefire stores its own temp files > * > @@ -2451,6 +2464,7 @@ public abstract class AbstractSurefireMojo > checksum.add( isParallelOptimized() ); > checksum.add( isTrimStackTrace() ); > checksum.add( getRemoteRepositories() ); > + checksum.add( getProjectRemoteRepositories() ); > checksum.add( isDisableXmlReport() ); > checksum.add( isUseSystemClassLoader() ); > checksum.add( isUseManifestOnlyJar() ); > @@ -2504,7 +2518,7 @@ public abstract class AbstractSurefireMojo > */ > private TestClassPath generateTestClasspath() > { > - @SuppressWarnings( "unchecked" ) Set classpathArtifacts > = getProject().getArtifacts(); > + Set classpathArtifacts = getProject().getArtifacts(); > > if ( getClasspathDependencyScopeExclude() != null && > !getClasspathDependencyScopeExclude().isEmpty() ) > { > @@ -2520,7 +2534,7 @@ public abstract class AbstractSurefireMojo > } > > return new TestClassPath( classpathArtifacts, > getClassesDirectory(), > - getTestClassesDirectory(), > getAdditionalClasspathElements(), getConsoleLogger() ); > + getTestClassesDirectory(), > getAdditionalClasspathElements() ); > } > > /** > @@ -2561,7 +2575,9 @@ public abstract class AbstractSurefireMojo > if ( existing == null ) > { > List items = new ArrayList<>(); > - for ( Artifact artifact : dependencyResolver.resolveArtifact( > surefireArtifact ).getArtifacts() ) > + Set booterArtifacts = > + surefireDependencyResolver.resolvePluginArtifact( > surefireArtifact ).getArtifacts(); > + for ( Artifact artifact : booterArtifacts ) > { > getConsoleLogger().debug( > "Adding to " + getPluginName() + " booter test > classpath: " + artifact.getFile().getAbsolutePath() > @@ -2665,7 +2681,7 @@ public abstract class AbstractSurefireMojo > + "is picking > up an old junit version" ); > } > throw new MojoFailureException( > "groups/excludedGroups require TestNG, JUnit48+ or JUnit 5 " > - + "on project test classpath" ); > + + "(a specific engine required on classpath) > on project test classpath" ); > } > } > > @@ -2789,7 +2805,7 @@ public abstract class AbstractSurefireMojo > { > Artifact surefireArtifact = getBooterArtifact(); > String version = surefireArtifact.getBaseVersion(); > - return dependencyResolver.getProviderClasspath( > "surefire-testng", version ); > + return surefireDependencyResolver.getProviderClasspath( > "surefire-testng", version ); > } > } > > @@ -2820,7 +2836,7 @@ public abstract class AbstractSurefireMojo > // add the JUnit provider as default - it doesn't require > JUnit to be present, > // since it supports POJO tests. > String version = surefireBooterArtifact.getBaseVersion(); > - return dependencyResolver.getProviderClasspath( > "surefire-junit3", version ); > + return surefireDependencyResolver.getProviderClasspath( > "surefire-junit3", version ); > } > } > > @@ -2859,18 +2875,23 @@ public abstract class AbstractSurefireMojo > public Set getProviderClasspath() > { > String version = surefireBooterArtifact.getBaseVersion(); > - return dependencyResolver.getProviderClasspath( > "surefire-junit4", version ); > + return surefireDependencyResolver.getProviderClasspath( > "surefire-junit4", version ); > } > } > > final class JUnitPlatformProviderInfo > implements ProviderInfo > { > - private final Artifact junitArtifact; > + private static final String PROVIDER_DEP_GID = > "org.junit.platform"; > + private static final String PROVIDER_DEP_AID = > "junit-platform-launcher"; > > - JUnitPlatformProviderInfo( Artifact junitArtifact ) > + private final Artifact junitPlatformArtifact; > + private final TestClassPath testClasspath; > + > + JUnitPlatformProviderInfo( Artifact junitPlatformArtifact, > TestClassPath testClasspath ) > { > - this.junitArtifact = junitArtifact; > + this.junitPlatformArtifact = junitPlatformArtifact; > + this.testClasspath = testClasspath; > } > > @Override > @@ -2883,7 +2904,7 @@ public abstract class AbstractSurefireMojo > @Override > public boolean isApplicable() > { > - return junitArtifact != null; > + return junitPlatformArtifact != null; > } > > @Override > @@ -2894,10 +2915,134 @@ public abstract class AbstractSurefireMojo > > @Override > @Nonnull > - public Set getProviderClasspath() > + public Set getProviderClasspath() throws > MojoExecutionException > { > - String version = surefireBooterArtifact.getBaseVersion(); > - return dependencyResolver.getProviderClasspath( > "surefire-junit-platform", version ); > + String surefireVersion = > surefireBooterArtifact.getBaseVersion(); > + Map providerArtifacts = > + surefireDependencyResolver.getProviderClasspathAsMap( > "surefire-junit-platform", surefireVersion ); > + Map testDependencies = > testClasspath.getTestDependencies(); > + > + if ( hasDependencyPlatformEngine( testDependencies ) ) > + { > + String filterTestDependency = > "org.junit.platform:junit-platform-engine"; > + getConsoleLogger().debug( "Test dependencies contain " + > filterTestDependency ); > + narrowProviderDependencies( filterTestDependency, > providerArtifacts, testDependencies ); > + } > + else > + { > + ProjectBuildingRequest request = > getSession().getProjectBuildingRequest(); > + Collection pluginDependencies = > getPluginDescriptor().getPlugin().getDependencies(); > + Set engines = > + > surefireDependencyResolver.resolvePluginDependencies( request, > pluginDependencies ); > + if ( hasDependencyPlatformEngine( engines ) ) > + { > + Map engineArtifacts = > artifactMapByVersionlessId( engines ); > + providerArtifacts.putAll( engineArtifacts ); > + alignVersions( providerArtifacts, engineArtifacts ); > + } > + else if ( hasDependencyJupiterAPI( testDependencies ) ) > + { > + String engineGroupId = "org.junit.jupiter"; > + String engineArtifactId = "junit-jupiter-engine"; > + String engineCoordinates = engineGroupId + ":" + > engineArtifactId; > + String api = "org.junit.jupiter:junit-jupiter-api"; > + getConsoleLogger().debug( "Test dependencies contain > " + api + ". Resolving " + engineCoordinates ); > + String engineVersion = testDependencies.get( api > ).getBaseVersion(); > + addEngineByApi( engineGroupId, engineArtifactId, > engineVersion, > + providerArtifacts, testDependencies ); > + } > + } > + providerArtifacts.keySet().removeAll( > testDependencies.keySet() ); > + return new LinkedHashSet<>( providerArtifacts.values() ); > + } > + > + private void addEngineByApi( String engineGroupId, String > engineArtifactId, String engineVersion, > + Map > providerArtifacts, Map testDependencies ) > + { > + providerArtifacts.keySet().removeAll( > testDependencies.keySet() ); > + for ( Artifact dep : resolve( engineGroupId, > engineArtifactId, engineVersion, null, "jar" ) ) > + { > + String key = dep.getGroupId() + ":" + dep.getArtifactId(); > + if ( !testDependencies.containsKey( key ) ) > + { > + providerArtifacts.put( key, dep ); > + } > + } > + alignVersions( providerArtifacts, testDependencies ); > + } > + > + private void narrowProviderDependencies( String > filterTestDependency, > + Map > providerArtifacts, > + Map > testDependencies ) > + { > + Artifact engine = testDependencies.get( filterTestDependency > ); > + String groupId = engine.getGroupId(); > + String artifactId = engine.getArtifactId(); > + String version = engine.getBaseVersion(); > + String classifier = engine.getClassifier(); > + String type = engine.getType(); > + for ( Artifact engineDep : resolve( groupId, artifactId, > version, classifier, type ) ) > + { > + providerArtifacts.remove( engineDep.getGroupId() + ":" + > engineDep.getArtifactId() ); > + getConsoleLogger().debug( "Removed artifact " + engineDep > + + " from provider. Already appears in test > classpath." ); > + } > + alignVersions( providerArtifacts, testDependencies ); > + } > + > + private void alignVersions( Map > providerArtifacts, > + Map > referencedDependencies ) > + { > + String version = referencedDependencies.get( > "org.junit.platform:junit-platform-commons" ).getBaseVersion(); > + for ( Artifact launcherArtifact : resolve( PROVIDER_DEP_GID, > PROVIDER_DEP_AID, version, null, "jar" ) ) > + { > + String key = launcherArtifact.getGroupId() + ":" + > launcherArtifact.getArtifactId(); > + if ( providerArtifacts.containsKey( key ) ) > + { > + providerArtifacts.put( key, launcherArtifact ); > + } > + } > + } > + > + private Set resolve( String g, String a, String v, > String c, String t ) > + { > + ArtifactHandler handler = > junitPlatformArtifact.getArtifactHandler(); > + Artifact artifact = new DefaultArtifact( g, a, v, null, t, c, > handler ); > + getConsoleLogger().debug( "Resolving artifact " + g + ":" + a > + ":" + v ); > + Set r = > surefireDependencyResolver.resolveProjectArtifact( artifact > ).getArtifacts(); > + getConsoleLogger().debug( "Resolved artifact " + g + ":" + a > + ":" + v + " to " + r ); > + return r; > + } > + > + private boolean hasDependencyJupiterAPI( Map > dependencies ) > + { > + return dependencies.containsKey( > "org.junit.jupiter:junit-jupiter-api" ) > + || hasGroupArtifactId( "org.junit.jupiter", > "junit-jupiter-api", getProject().getArtifact() ); > + } > + > + private boolean hasDependencyPlatformEngine( Map Artifact> dependencies ) > + { > + return dependencies.containsKey( > "org.junit.platform:junit-platform-engine" ) > + || hasGroupArtifactId( "org.junit.platform", > "junit-platform-engine", getProject().getArtifact() ); > + } > + > + private boolean hasDependencyPlatformEngine( Collection > dependencies ) > + { > + if ( hasGroupArtifactId( "org.junit.platform", > "junit-platform-engine", getProject().getArtifact() ) ) > + { > + return true; > + } > + > + for ( Artifact dependency : dependencies ) > + { > + if ( dependency.getGroupId().equals( "org.junit.platform" > ) > + && dependency.getArtifactId().equals( > "junit-platform-engine" ) ) > + { > + return true; > + } > + } > + > + return false; > } > } > > @@ -2945,7 +3090,7 @@ public abstract class AbstractSurefireMojo > public Set getProviderClasspath() > { > String version = surefireBooterArtifact.getBaseVersion(); > - return dependencyResolver.getProviderClasspath( > "surefire-junit47", version ); > + return surefireDependencyResolver.getProviderClasspath( > "surefire-junit47", version ); > } > } > > @@ -2993,7 +3138,7 @@ public abstract class AbstractSurefireMojo > @Nonnull > public Set getProviderClasspath() > { > - return dependencyResolver.addProviderToClasspath( > getPluginArtifactMap(), getMojoArtifact(), > + return surefireDependencyResolver.addProviderToClasspath( > getPluginArtifactMap(), getMojoArtifact(), > getCommonArtifact(), getApiArtifact(), > getLoggerApiArtifact() ); > } > } > @@ -3176,7 +3321,6 @@ public abstract class AbstractSurefireMojo > this.projectArtifactMap = projectArtifactMap; > } > > - > public String getReportNameSuffix() > { > return reportNameSuffix; > @@ -3305,17 +3449,6 @@ public abstract class AbstractSurefireMojo > this.junitArtifactName = junitArtifactName; > } > > - public String getJunitPlatformArtifactName() > - { > - return junitPlatformArtifactName; > - } > - > - @SuppressWarnings( "UnusedDeclaration" ) > - public void setJunitPlatformArtifactName( String > junitPlatformArtifactName ) > - { > - this.junitPlatformArtifactName = junitPlatformArtifactName; > - } > - > public String getTestNGArtifactName() > { > return testNGArtifactName; > @@ -3423,6 +3556,17 @@ public abstract class AbstractSurefireMojo > this.trimStackTrace = trimStackTrace; > } > > + public List getProjectRemoteRepositories() > + { > + return projectRemoteRepositories; > + } > + > + @SuppressWarnings( "UnusedDeclaration" ) > + public void setProjectRemoteRepositories( List > projectRemoteRepositories ) > + { > + this.projectRemoteRepositories = projectRemoteRepositories; > + } > + > public List getRemoteRepositories() > { > return remoteRepositories; > @@ -3518,6 +3662,12 @@ public abstract class AbstractSurefireMojo > this.dependenciesToScan = dependenciesToScan; > } > > + @SuppressWarnings( "UnusedDeclaration" ) > + void setPluginDescriptor( PluginDescriptor pluginDescriptor ) > + { > + this.pluginDescriptor = pluginDescriptor; > + } > + > public PluginDescriptor getPluginDescriptor() > { > return pluginDescriptor; > diff --git > a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java > b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java > index cb63cc1..fea74fd 100644 > --- > a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java > +++ > b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java > @@ -36,7 +36,7 @@ public interface ProviderInfo > boolean isApplicable(); > > @Nonnull > - Set getProviderClasspath(); > + Set getProviderClasspath() throws MojoExecutionException; > > void addProviderProperties() throws MojoExecutionException; > } > 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 b255f38..170107c 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 > @@ -19,6 +19,7 @@ package org.apache.maven.plugin.surefire; > * under the License. > */ > > +import java.util.Collection; > import java.util.Iterator; > import java.util.LinkedHashSet; > import java.util.List; > @@ -29,20 +30,29 @@ import org.apache.maven.artifact.Artifact; > 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.filter.ExcludesArtifactFilter; > +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; > import org.apache.maven.artifact.versioning.DefaultArtifactVersion; > import > org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; > import > org.apache.maven.artifact.versioning.OverConstrainedVersionException; > import org.apache.maven.artifact.versioning.VersionRange; > import org.apache.maven.model.Dependency; > +import org.apache.maven.plugin.MojoExecutionException; > import org.apache.maven.plugin.surefire.log.api.ConsoleLogger; > +import org.apache.maven.project.ProjectBuildingRequest; > import org.apache.maven.repository.RepositorySystem; > +import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter; > +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; > +import > org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; > +import > org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; > > import javax.annotation.Nonnull; > import javax.annotation.Nullable; > > -import static java.util.Collections.singletonList; > -import static org.apache.maven.artifact.Artifact.SCOPE_TEST; > +import static java.util.Arrays.asList; > +import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE; > +import static > org.apache.maven.artifact.Artifact.SCOPE_COMPILE_PLUS_RUNTIME; > +import static org.apache.maven.artifact.Artifact.SCOPE_RUNTIME; > +import static > org.apache.maven.artifact.ArtifactUtils.artifactMapByVersionlessId; > import static > org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec; > > /** > @@ -76,19 +86,27 @@ final class SurefireDependencyResolver > > private final ArtifactRepository localRepository; > > - private final List remoteRepositories; > + private final List pluginRemoteRepositories; > + > + private final List projectRemoteRepositories; > > private final String pluginName; > > + private final DependencyResolver depencencyResolver; > + > SurefireDependencyResolver( RepositorySystem repositorySystem, > ConsoleLogger log, > ArtifactRepository localRepository, > - List > remoteRepositories, String pluginName ) > + List > pluginRemoteRepositories, > + List > projectRemoteRepositories, String pluginName, > + DependencyResolver depencencyResolver ) > { > this.repositorySystem = repositorySystem; > this.log = log; > this.localRepository = localRepository; > - this.remoteRepositories = remoteRepositories; > + this.pluginRemoteRepositories = pluginRemoteRepositories; > + this.projectRemoteRepositories = projectRemoteRepositories; > this.pluginName = pluginName; > + this.depencencyResolver = depencencyResolver; > } > > static boolean isWithinVersionSpec( @Nullable Artifact artifact, > @Nonnull String versionSpec ) > @@ -115,23 +133,46 @@ final class SurefireDependencyResolver > } > } > > - ArtifactResolutionResult resolveArtifact( Artifact providerArtifact ) > + Set resolvePluginDependencies( ProjectBuildingRequest > request, Collection pluginDependencies ) > + throws MojoExecutionException > { > - return resolveArtifact( providerArtifact, null ); > + try > + { > + Iterable resolvedPluginDependencies = > depencencyResolver.resolveDependencies( request, > + pluginDependencies, null, ScopeFilter.including( > SCOPE_COMPILE, SCOPE_RUNTIME ) ); > + > + Set resolved = new LinkedHashSet<>(); > + for ( ArtifactResult resolvedPluginDependency : > resolvedPluginDependencies ) > + { > + resolved.add( resolvedPluginDependency.getArtifact() ); > + } > + return resolved; > + } > + catch ( DependencyResolverException e ) > + { > + throw new MojoExecutionException( e.getLocalizedMessage(), e > ); > + } > } > > - private ArtifactResolutionResult resolveArtifact( Artifact > providerArtifact, @Nullable Artifact excludeArtifact ) > + ArtifactResolutionResult resolvePluginArtifact( Artifact artifact ) > + { > + return resolveArtifact( artifact, pluginRemoteRepositories ); > + } > + > + ArtifactResolutionResult resolveProjectArtifact( Artifact artifact ) > + { > + return resolveArtifact( artifact, projectRemoteRepositories ); > + } > + > + private ArtifactResolutionResult resolveArtifact( Artifact artifact, > List repositories ) > { > ArtifactResolutionRequest request = new > ArtifactResolutionRequest() > - .setArtifact( > providerArtifact ) > - > .setRemoteRepositories( remoteRepositories ) > - .setLocalRepository( > localRepository ) > - > .setResolveTransitively( true ); > - if ( excludeArtifact != null ) > - { > - String pattern = excludeArtifact.getGroupId() + ":" + > excludeArtifact.getArtifactId(); > - request.setCollectionFilter( new ExcludesArtifactFilter( > singletonList( pattern ) ) ); > - } > + .setArtifact( artifact ) > + .setLocalRepository( localRepository ) > + .setResolveTransitively( true ) > + .setCollectionFilter( new RuntimeArtifactFilter() ) > + .setRemoteRepositories( repositories ); > + > return repositorySystem.resolve( request ); > } > > @@ -142,7 +183,7 @@ final class SurefireDependencyResolver > > Artifact providerArtifact = > repositorySystem.createDependencyArtifact( provider ); > > - ArtifactResolutionResult result = resolveArtifact( > providerArtifact ); > + ArtifactResolutionResult result = resolvePluginArtifact( > providerArtifact ); > > if ( log.isDebugEnabled() ) > { > @@ -157,17 +198,23 @@ final class SurefireDependencyResolver > return orderProviderArtifacts( result.getArtifacts() ); > } > > + @Nonnull > + Map getProviderClasspathAsMap( String > providerArtifactId, String providerVersion ) > + { > + return artifactMapByVersionlessId( getProviderClasspath( > providerArtifactId, providerVersion ) ); > + } > + > Set addProviderToClasspath( Map > pluginArtifactMap, Artifact mojoPluginArtifact, > Artifact surefireCommon, > Artifact surefireApi, Artifact surefireLoggerApi ) > { > Set providerArtifacts = new LinkedHashSet<>(); > - ArtifactResolutionResult artifactResolutionResult = > resolveArtifact( mojoPluginArtifact ); > + ArtifactResolutionResult artifactResolutionResult = > resolvePluginArtifact( mojoPluginArtifact ); > for ( Artifact artifact : pluginArtifactMap.values() ) > { > if ( !artifactResolutionResult.getArtifacts().contains( > artifact ) ) > { > providerArtifacts.add( artifact ); > - for ( Artifact dependency : resolveArtifact( artifact > ).getArtifacts() ) > + for ( Artifact dependency : resolvePluginArtifact( > artifact ).getArtifacts() ) > { > String groupId = dependency.getGroupId(); > String artifactId = dependency.getArtifactId(); > @@ -219,7 +266,19 @@ final class SurefireDependencyResolver > dependency.setArtifactId( providerArtifactId ); > dependency.setVersion( providerVersion ); > dependency.setType( "jar" ); > - dependency.setScope( SCOPE_TEST ); > return dependency; > } > + > + static class RuntimeArtifactFilter implements ArtifactFilter > + { > + private static final Collection SCOPES = > + asList( SCOPE_COMPILE, SCOPE_COMPILE_PLUS_RUNTIME, > SCOPE_RUNTIME ); > + > + @Override > + public boolean include( Artifact artifact ) > + { > + String scope = artifact.getScope(); > + return !artifact.isOptional() && ( scope == null || > SCOPES.contains( scope ) ); > + } > + } > } > diff --git > a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/TestClassPath.java > b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/TestClassPath.java > index ee8fadb..3a37816 100644 > --- > a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/TestClassPath.java > +++ > b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/TestClassPath.java > @@ -20,14 +20,13 @@ package org.apache.maven.plugin.surefire; > */ > > import org.apache.maven.artifact.Artifact; > -import org.apache.maven.plugin.surefire.log.api.ConsoleLogger; > import org.apache.maven.surefire.booter.Classpath; > > import java.io.File; > import java.util.ArrayList; > -import java.util.Iterator; > +import java.util.LinkedHashMap; > import java.util.List; > -import java.util.Set; > +import java.util.Map; > > import static java.util.Collections.addAll; > import static org.apache.maven.shared.utils.StringUtils.split; > @@ -38,45 +37,26 @@ final class TestClassPath > private final File classesDirectory; > private final File testClassesDirectory; > private final String[] additionalClasspathElements; > - private final ConsoleLogger logger; > > TestClassPath( Iterable artifacts, > File classesDirectory, > File testClassesDirectory, > - String[] additionalClasspathElements, > - ConsoleLogger logger ) > + String[] additionalClasspathElements ) > { > this.artifacts = artifacts; > this.classesDirectory = classesDirectory; > this.testClassesDirectory = testClassesDirectory; > this.additionalClasspathElements = additionalClasspathElements; > - this.logger = logger; > } > > - void avoidArtifactDuplicates( Set providerArtifacts ) > + Map getTestDependencies() > { > + Map artifactMapping = new LinkedHashMap<>(); > for ( Artifact artifact : artifacts ) > { > - Iterator it = providerArtifacts.iterator(); > - while ( it.hasNext() ) > - { > - Artifact providerArtifact = it.next(); > - String classifier1 = providerArtifact.getClassifier(); > - String classifier2 = artifact.getClassifier(); > - if ( providerArtifact.getGroupId().equals( > artifact.getGroupId() ) > - && providerArtifact.getArtifactId().equals( > artifact.getArtifactId() ) > - && providerArtifact.getType().equals( > artifact.getType() ) > - && ( classifier1 == null ? classifier2 == null : > classifier1.equals( classifier2 ) ) ) > - { > - it.remove(); > - if ( logger.isDebugEnabled() ) > - { > - logger.debug( "Removed artifact " + > providerArtifact + " from provider. " > - + "Already appears in test classpath." ); > - } > - } > - } > + artifactMapping.put( artifact.getGroupId() + ":" + > artifact.getArtifactId(), artifact ); > } > + return artifactMapping; > } > > Classpath toClasspath() > diff --git > a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java > b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java > index 0f9ee80..2d268bc 100644 > --- > a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java > +++ > b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java > @@ -108,7 +108,7 @@ public class AbstractSurefireMojoJava7PlusTest > > TestClassPath testClasspath = > new TestClassPath( asList( modular, nonModular, junit, > hamcrest ), classesDir, testClassesDir, > - null, null ); > + null ); > > doReturn( testClasspath ).when( mojo, "generateTestClasspath" ); > doReturn( 1 ).when( mojo, "getEffectiveForkCount" ); > @@ -171,11 +171,10 @@ public class AbstractSurefireMojoJava7PlusTest > > StartupConfiguration conf = invokeMethod( mojo, > "newStartupConfigWithModularPath", > classLoaderConfiguration, providerClasspath, > "org.asf.Provider", moduleInfo, scanResult, > - "" ); > + "", testClasspath ); > > verify( mojo, times( 1 ) ).effectiveIsEnableAssertions(); > verify( mojo, times( 1 ) ).isChildDelegation(); > - verifyPrivate( mojo, times( 1 ) ).invoke( "generateTestClasspath" > ); > verify( mojo, times( 1 ) ).getEffectiveForkCount(); > verify( mojo, times( 1 ) ).getTestClassesDirectory(); > verify( scanResult, times( 1 ) ).getClasses(); > 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 a6fc708..080f2b5 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 > @@ -22,9 +22,22 @@ package org.apache.maven.plugin.surefire; > import org.apache.maven.artifact.Artifact; > 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.ArtifactResolutionRequest; > +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; > import org.apache.maven.artifact.versioning.VersionRange; > +import org.apache.maven.execution.MavenSession; > +import org.apache.maven.model.Dependency; > +import org.apache.maven.model.Plugin; > +import org.apache.maven.plugin.descriptor.PluginDescriptor; > +import > org.apache.maven.plugin.surefire.AbstractSurefireMojo.JUnitPlatformProviderInfo; > import org.apache.maven.plugin.surefire.log.PluginConsoleLogger; > import org.apache.maven.project.MavenProject; > +import org.apache.maven.project.ProjectBuildingRequest; > +import org.apache.maven.repository.RepositorySystem; > +import > org.apache.maven.shared.artifact.filter.resolve.TransformableFilter; > +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; > +import > org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; > import org.apache.maven.surefire.booter.ClassLoaderConfiguration; > import org.apache.maven.surefire.booter.Classpath; > import org.apache.maven.surefire.booter.StartupConfiguration; > @@ -33,7 +46,10 @@ import org.codehaus.plexus.logging.Logger; > import org.junit.Test; > import org.junit.runner.RunWith; > import org.mockito.ArgumentCaptor; > +import org.mockito.ArgumentMatchers; > import org.mockito.Mock; > +import org.mockito.invocation.InvocationOnMock; > +import org.mockito.stubbing.Answer; > import org.powermock.core.classloader.annotations.PrepareForTest; > import org.powermock.modules.junit4.PowerMockRunner; > > @@ -41,6 +57,7 @@ import java.io.File; > import java.io.IOException; > import java.util.ArrayList; > import java.util.Collection; > +import java.util.Collections; > import java.util.HashMap; > import java.util.HashSet; > import java.util.LinkedHashSet; > @@ -50,13 +67,14 @@ import java.util.Set; > > import static java.io.File.separatorChar; > import static java.util.Arrays.asList; > -import static java.util.Collections.singleton; > +import static java.util.Collections.*; > import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS; > import static > org.apache.maven.artifact.versioning.VersionRange.createFromVersion; > import static > org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec; > import static org.fest.assertions.Assertions.assertThat; > -import static org.mockito.ArgumentMatchers.any; > -import static org.mockito.ArgumentMatchers.anyString; > +import static org.fest.assertions.MapAssert.entry; > +import static org.junit.Assert.fail; > +import static org.mockito.ArgumentMatchers.*; > import static org.mockito.Mockito.times; > import static org.mockito.Mockito.when; > import static org.mockito.Mockito.verify; > @@ -247,7 +265,7 @@ public class AbstractSurefireMojoTest > File classesDir = mockFile( "classes" ); > File testClassesDir = mockFile( "test-classes" ); > TestClassPath testClasspath = > - new TestClassPath( asList( junit, hamcrest ), classesDir, > testClassesDir, null, null ); > + new TestClassPath( asList( junit, hamcrest ), classesDir, > testClassesDir, null ); > > doReturn( testClasspath ).when( mojo, "generateTestClasspath" ); > doReturn( 1 ).when( mojo, "getEffectiveForkCount" ); > @@ -267,11 +285,10 @@ public class AbstractSurefireMojoTest > when( mojo.getConsoleLogger() ).thenReturn( new > PluginConsoleLogger( logger ) ); > > StartupConfiguration conf = invokeMethod( mojo, > "newStartupConfigWithClasspath", > - classLoaderConfiguration, providerArtifacts, > "org.asf.Provider" ); > + classLoaderConfiguration, providerArtifacts, > "org.asf.Provider", testClasspath ); > > verify( mojo, times( 1 ) ).effectiveIsEnableAssertions(); > verify( mojo, times( 1 ) ).isChildDelegation(); > - verifyPrivate( mojo, times( 1 ) ).invoke( "generateTestClasspath" > ); > verify( mojo, times( 1 ) ).getEffectiveForkCount(); > ArgumentCaptor argument = ArgumentCaptor.forClass( > String.class ); > verify( logger, times( 6 ) ).debug( argument.capture() ); > @@ -360,9 +377,1214 @@ public class AbstractSurefireMojoTest > .isDirectory(); > } > > + @Test > + public void shouldSmartlyResolveJUnit5ProviderWithJUnit4() throws > Exception > + { > + MavenProject mavenProject = new MavenProject(); > + mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", > createFromVersion( "1.0.0" ), > + null, "jar", null, mock( ArtifactHandler.class ) ) ); > + mojo.setProject( mavenProject ); > + > + final VersionRange surefireVersion = createFromVersion( "1" ); > + > + Artifact junitPlatformArtifact = new DefaultArtifact( > "org.apache.maven.surefire", > + "surefire-junit-platform", surefireVersion, null, "jar", > null, mock( ArtifactHandler.cla --0000000000006626dc05830d845b--