You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2020/05/16 01:00:10 UTC

[maven-surefire] 01/01: unit tests

This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a commit to branch SUREFIRE-1570
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit 8707187b69bd34d0af944b64e0566b1a7aec5a2a
Author: tibordigana <ti...@apache.org>
AuthorDate: Sat May 16 02:53:45 2020 +0200

    unit tests
---
 .../plugin/surefire/AbstractSurefireMojo.java      |  46 ++---
 .../maven/plugin/surefire/JdkAttributes.java       |  21 ++-
 ...tributes.java => ResolvePathResultWrapper.java} |  28 +--
 .../booterclient/DefaultForkConfiguration.java     |   2 +-
 .../plugin/surefire/booterclient/Platform.java     |   2 +-
 .../plugin/surefire/AbstractSurefireMojoTest.java  | 210 ++++++++++++++++++++-
 .../AbstractSurefireMojoToolchainsTest.java        |  22 ++-
 .../apache/maven/plugin/surefire/module-info.class | Bin 0 -> 149 bytes
 8 files changed, 275 insertions(+), 56 deletions(-)

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 9790371..490c6da 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
@@ -103,7 +103,6 @@ import java.io.IOException;
 import java.lang.reflect.Method;
 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;
@@ -1379,29 +1378,29 @@ public abstract class AbstractSurefireMojo
         this.dependencyResolver = dependencyResolver;
     }
 
-    private boolean existsModuleDescriptor()
+    private boolean existsModuleDescriptor( File jdkHome )
     {
-        return getModuleDescriptor() != null;
+        return findModuleDescriptor( jdkHome ).getResolvePathResult() != null;
     }
 
-    private ResolvePathResult getModuleDescriptor()
+    private ResolvePathResultWrapper findModuleDescriptor( File jdkHome )
     {
         File mainBuildPath = getMainBuildPath();
 
         if ( mainBuildPath.isDirectory() && !new File( mainBuildPath, "module-info.class" ).exists() )
         {
-            return null;
+            return new ResolvePathResultWrapper( null, true );
         }
 
         try
         {
-            // .setJdkHome(  )
-            ResolvePathResult result = getLocationManager().resolvePath( ResolvePathRequest.ofFile( mainBuildPath ) );
-            return result.getModuleNameSource() == null ? null : result;
+            ResolvePathRequest<?> request = ResolvePathRequest.ofFile( mainBuildPath ).setJdkHome( jdkHome );
+            ResolvePathResult result = getLocationManager().resolvePath( request );
+            return new ResolvePathResultWrapper( result.getModuleNameSource() == null ? null : result, true );
         }
         catch ( Exception e )
         {
-            return null;
+            return new ResolvePathResultWrapper( null, true );
         }
     }
 
@@ -1409,7 +1408,7 @@ public abstract class AbstractSurefireMojo
     {
         return useModulePath()
                 && platform.getJdkExecAttributesForTests().isJava9AtLeast()
-                && existsModuleDescriptor();
+                && existsModuleDescriptor( platform.getJdkExecAttributesForTests().getJdkHome() );
     }
 
     /**
@@ -1875,16 +1874,12 @@ public abstract class AbstractSurefireMojo
             String providerName = provider.getProviderName();
             if ( isForking && canExecuteProviderWithModularPath( platform ) )
             {
-                String jvmExecutable = platform.getJdkExecAttributesForTests().getJvmExecutable();
-                String javaHome = Paths.get( jvmExecutable )
-                        .toAbsolutePath()
-                        .normalize()
-                        .getParent()
-                        .getParent()
-                        .toString();
+                JdkAttributes jdkAttributes = platform.getJdkExecAttributesForTests();
+                File jdkHome = jdkAttributes.getJdkHome();
+                ResolvePathResult resolvePathResult = findModuleDescriptor( jdkHome ).getResolvePathResult();
 
                 return newStartupConfigWithModularPath( classLoaderConfiguration, providerArtifacts, providerName,
-                        getModuleDescriptor(), scanResult, javaHome, testClasspathWrapper );
+                        resolvePathResult, scanResult, jdkHome.getAbsolutePath(), testClasspathWrapper );
             }
             else
             {
@@ -2551,13 +2546,17 @@ public abstract class AbstractSurefireMojo
             }
 
             File jdkHome = toJdkHomeFromJvmExec( pathToJava.getPath() );
-            if ( !environmentVariables.containsKey( "JAVA_HOME" ) )
+            if ( jdkHome == null )
+            {
+                getConsoleLogger().warning( "Cannot determine JAVA_HOME of jvm exec path " + pathToJava );
+            }
+            else if ( !environmentVariables.containsKey( "JAVA_HOME" ) )
             {
                 environmentVariables.put( "JAVA_HOME", jdkHome.getAbsolutePath() );
             }
             BigDecimal version = jdkHome == null ? null : toJdkVersionFromReleaseFile( jdkHome );
             boolean javaVersion9 = version == null ? isJava9AtLeast( pathToJava.getPath() ) : isJava9AtLeast( version );
-            return new JdkAttributes( pathToJava.getPath(), javaVersion9 );
+            return new JdkAttributes( pathToJava, jdkHome, javaVersion9 );
         }
 
         if ( toolchain != null )
@@ -2566,6 +2565,7 @@ public abstract class AbstractSurefireMojo
             if ( isNotEmpty( jvmToUse ) )
             {
                 boolean javaVersion9 = false;
+                String jdkHome = null;
 
                 if ( toolchain instanceof DefaultToolchain )
                 {
@@ -2579,7 +2579,8 @@ public abstract class AbstractSurefireMojo
                     DefaultJavaToolChain defaultJavaToolChain = (DefaultJavaToolChain) toolchain;
                     if ( !environmentVariables.containsKey( "JAVA_HOME" ) )
                     {
-                        environmentVariables.put( "JAVA_HOME", defaultJavaToolChain.getJavaHome() );
+                        jdkHome = defaultJavaToolChain.getJavaHome();
+                        environmentVariables.put( "JAVA_HOME", jdkHome );
                     }
                 }
 
@@ -2588,7 +2589,8 @@ public abstract class AbstractSurefireMojo
                     javaVersion9 = isJava9AtLeast( jvmToUse );
                 }
 
-                return new JdkAttributes( jvmToUse, javaVersion9 );
+                return new JdkAttributes( new File( jvmToUse ),
+                    jdkHome == null ? toJdkHomeFromJvmExec( jvmToUse ) : new File( jdkHome ), javaVersion9 );
             }
         }
 
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java
index 96049a5..f8ab5f7 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java
@@ -19,7 +19,10 @@ package org.apache.maven.plugin.surefire;
  * under the License.
  */
 
+import java.io.File;
+
 import static java.util.Objects.requireNonNull;
+import static org.apache.maven.surefire.booter.SystemUtils.toJdkHomeFromJvmExec;
 
 /**
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
@@ -27,20 +30,32 @@ import static java.util.Objects.requireNonNull;
  */
 public final class JdkAttributes
 {
-    private final String jvmExecutable;
+    private final File jvmExecutable;
+    private final File jdkHome;
     private final boolean java9AtLeast;
 
-    public JdkAttributes( String jvmExecutable, boolean java9AtLeast )
+    public JdkAttributes( File jvmExecutable, File jdkHome, boolean java9AtLeast )
     {
         this.jvmExecutable = requireNonNull( jvmExecutable, "null path to java executable" );
+        this.jdkHome = jdkHome;
         this.java9AtLeast = java9AtLeast;
     }
 
-    public String getJvmExecutable()
+    public JdkAttributes( String jvmExecutable, boolean java9AtLeast )
+    {
+        this( new File( jvmExecutable ), toJdkHomeFromJvmExec( jvmExecutable ), java9AtLeast );
+    }
+
+    public File getJvmExecutable()
     {
         return jvmExecutable;
     }
 
+    public File getJdkHome()
+    {
+        return jdkHome;
+    }
+
     public boolean isJava9AtLeast()
     {
         return java9AtLeast;
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ResolvePathResultWrapper.java
similarity index 55%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java
copy to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ResolvePathResultWrapper.java
index 96049a5..9197d89 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ResolvePathResultWrapper.java
@@ -19,30 +19,32 @@ package org.apache.maven.plugin.surefire;
  * under the License.
  */
 
-import static java.util.Objects.requireNonNull;
+import org.codehaus.plexus.languages.java.jpms.ResolvePathResult;
 
 /**
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.20.1
+ * Wraps {@link ResolvePathResult} and place marker.
  */
-public final class JdkAttributes
+final class ResolvePathResultWrapper
 {
-    private final String jvmExecutable;
-    private final boolean java9AtLeast;
+    private final ResolvePathResult resolvePathResult;
+    private final boolean isMainModuleDescriptor;
 
-    public JdkAttributes( String jvmExecutable, boolean java9AtLeast )
+    ResolvePathResultWrapper( ResolvePathResult resolvePathResult, boolean isMainModuleDescriptor )
     {
-        this.jvmExecutable = requireNonNull( jvmExecutable, "null path to java executable" );
-        this.java9AtLeast = java9AtLeast;
+        this.resolvePathResult = resolvePathResult;
+        this.isMainModuleDescriptor = isMainModuleDescriptor;
     }
 
-    public String getJvmExecutable()
+    ResolvePathResult getResolvePathResult()
     {
-        return jvmExecutable;
+        return resolvePathResult;
     }
 
-    public boolean isJava9AtLeast()
+    /**
+     * @return {@code true} if module-info appears in src/main/java module
+     */
+    boolean isMainModuleDescriptor()
     {
-        return java9AtLeast;
+        return isMainModuleDescriptor;
     }
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
index 443bf45..af09d67 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
@@ -144,7 +144,7 @@ public abstract class DefaultForkConfiguration
             cli.addEnvironment( entry.getKey(), value == null ? "" : value );
         }
 
-        cli.setExecutable( getJdkForTests().getJvmExecutable() );
+        cli.setExecutable( getJdkForTests().getJvmExecutable().getAbsolutePath() );
 
         String jvmArgLine = newJvmArgLine( forkNumber );
         if ( !jvmArgLine.isEmpty() )
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/Platform.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/Platform.java
index 074a3cb..14196f8 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/Platform.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/Platform.java
@@ -38,7 +38,7 @@ public final class Platform
 {
     private final RunnableFuture<Long> pluginPidJob;
 
-    private volatile JdkAttributes jdk;
+    private final JdkAttributes jdk;
 
     public Platform()
     {
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 3d366aa..bbef6e2 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
@@ -33,6 +33,7 @@ import org.apache.maven.model.Plugin;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
 import org.apache.maven.plugin.surefire.AbstractSurefireMojo.JUnitPlatformProviderInfo;
+import org.apache.maven.plugin.surefire.booterclient.Platform;
 import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.ProjectBuildingRequest;
@@ -43,15 +44,22 @@ import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
 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.ModularClasspathConfiguration;
 import org.apache.maven.surefire.booter.StartupConfiguration;
 import org.apache.maven.surefire.extensions.ForkNodeFactory;
 import org.apache.maven.surefire.suite.RunResult;
+import org.apache.maven.surefire.util.DefaultScanResult;
 import org.apache.maven.toolchain.Toolchain;
+import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor;
+import org.codehaus.plexus.languages.java.jpms.LocationManager;
+import org.codehaus.plexus.languages.java.jpms.ResolvePathRequest;
+import org.codehaus.plexus.languages.java.jpms.ResolvePathResult;
 import org.codehaus.plexus.logging.Logger;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -63,6 +71,8 @@ import org.powermock.modules.junit4.PowerMockRunner;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -75,21 +85,25 @@ import java.util.Map;
 import java.util.Set;
 
 import static java.io.File.separatorChar;
+import static java.nio.file.Files.write;
 import static java.util.Arrays.asList;
 import static java.util.Collections.emptySet;
 import static java.util.Collections.singleton;
 import static java.util.Collections.singletonList;
-import static org.apache.maven.surefire.shared.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.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_9;
+import static org.apache.maven.surefire.shared.lang3.JavaVersion.JAVA_RECENT;
+import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
+import static org.codehaus.plexus.languages.java.jpms.ModuleNameSource.MODULEDESCRIPTOR;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.fest.assertions.MapAssert.entry;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static org.powermock.api.mockito.PowerMockito.doNothing;
 import static org.powermock.api.mockito.PowerMockito.doReturn;
 import static org.powermock.api.mockito.PowerMockito.mock;
@@ -109,6 +123,9 @@ public class AbstractSurefireMojoTest
     @Rule
     public final ExpectedException e = ExpectedException.none();
 
+    @Rule
+    public final TemporaryFolder tempFolder = new TemporaryFolder();
+
     @Mock
     private ArtifactHandler handler;
 
@@ -140,6 +157,119 @@ public class AbstractSurefireMojoTest
     }
 
     @Test
+    public void noModuleDescriptorFile() throws Exception
+    {
+        AbstractSurefireMojo mojo = spy( new Mojo() );
+        mojo.setMainBuildPath( tempFolder.newFolder() );
+        File jdkHome = new File( System.getProperty( "java.home" ) );
+        ResolvePathResultWrapper wrapper = invokeMethod( mojo, "findModuleDescriptor", jdkHome );
+
+        assertThat( wrapper )
+            .isNotNull();
+
+        assertThat( wrapper.getResolvePathResult() )
+            .isNull();
+
+        assertThat( invokeMethod( mojo, "existsModuleDescriptor", jdkHome ) )
+            .isEqualTo( false );
+
+        when( mojo.useModulePath() ).thenReturn( true );
+
+        File jvmExecutable = new File( jdkHome, IS_OS_WINDOWS ? "bin\\java.exe" : "bin/java" );
+        JdkAttributes jdkAttributes = new JdkAttributes( jvmExecutable, jdkHome, true );
+        Platform platform = new Platform().withJdkExecAttributesForTests( jdkAttributes );
+        assertThat( invokeMethod( mojo, "canExecuteProviderWithModularPath", platform ) )
+            .isEqualTo( false );
+    }
+
+    @Test
+    public void correctModuleDescriptor() throws Exception
+    {
+        AbstractSurefireMojo mojo = spy( new Mojo() );
+        LocationManager locationManager = mock( LocationManager.class );
+        ResolvePathResult result = mock( ResolvePathResult.class );
+        when( result.getModuleNameSource() ).thenReturn( MODULEDESCRIPTOR );
+        JavaModuleDescriptor descriptor = mock( JavaModuleDescriptor.class );
+        when( result.getModuleDescriptor() ).thenReturn( descriptor );
+        when( locationManager.resolvePath( any( ResolvePathRequest.class ) ) ).thenReturn( result );
+        doReturn( locationManager )
+            .when( mojo, "getLocationManager" );
+        File classesDir = tempFolder.newFolder();
+        mojo.setMainBuildPath( classesDir );
+        File descriptorFile = new File( classesDir, "module-info.class" );
+        assertThat( descriptorFile.createNewFile() ).isTrue();
+        File jdkHome = new File( System.getProperty( "java.home" ) );
+        ResolvePathResultWrapper wrapper = invokeMethod( mojo, "findModuleDescriptor", jdkHome );
+
+        assertThat( wrapper )
+            .isNotNull();
+
+        assertThat( wrapper.getResolvePathResult() )
+            .isSameAs( result );
+
+        assertThat( wrapper.getResolvePathResult().getModuleNameSource() )
+            .isSameAs( MODULEDESCRIPTOR );
+
+        assertThat( wrapper.getResolvePathResult().getModuleDescriptor() )
+            .isSameAs( descriptor );
+
+        assertThat( invokeMethod( mojo, "existsModuleDescriptor", jdkHome ) )
+            .isEqualTo( true );
+
+        when( mojo.useModulePath() ).thenReturn( true );
+
+        File jvmExecutable = new File( jdkHome, IS_OS_WINDOWS ? "bin\\java.exe" : "bin/java" );
+        JdkAttributes jdkAttributes = new JdkAttributes( jvmExecutable, jdkHome, true );
+        Platform platform = new Platform().withJdkExecAttributesForTests( jdkAttributes );
+        assertThat( invokeMethod( mojo, "canExecuteProviderWithModularPath", platform ) )
+            .isEqualTo( true );
+
+        jdkAttributes = new JdkAttributes( jvmExecutable, jdkHome, false );
+        platform = new Platform().withJdkExecAttributesForTests( jdkAttributes );
+        assertThat( invokeMethod( mojo, "canExecuteProviderWithModularPath", platform ) )
+            .isEqualTo( false );
+
+        when( mojo.useModulePath() ).thenReturn( false );
+
+        jdkAttributes = new JdkAttributes( jvmExecutable, jdkHome, true );
+        platform = new Platform().withJdkExecAttributesForTests( jdkAttributes );
+        assertThat( invokeMethod( mojo, "canExecuteProviderWithModularPath", platform ) )
+            .isEqualTo( false );
+    }
+
+    @Test
+    @SuppressWarnings( "checkstyle:magicnumber" )
+    public void corruptedModuleDescriptor() throws Exception
+    {
+        if ( !JAVA_RECENT.atLeast( JAVA_9 ) )
+        {
+            return;
+        }
+
+        AbstractSurefireMojo mojo = spy( new Mojo() );
+        doReturn( new LocationManager() )
+            .when( mojo, "getLocationManager" );
+        File classesDir = tempFolder.newFolder();
+        mojo.setMainBuildPath( classesDir );
+
+        File descriptorFile = new File( classesDir, "module-info.class" );
+        assertThat( descriptorFile.createNewFile() ).isTrue();
+        write( descriptorFile.toPath(), new byte[]{(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE} );
+
+        File jdkHome = new File( System.getProperty( "java.home" ) );
+        ResolvePathResultWrapper wrapper = invokeMethod( mojo, "findModuleDescriptor", jdkHome );
+
+        assertThat( wrapper )
+            .isNotNull();
+
+        assertThat( wrapper.getResolvePathResult() )
+            .isNull();
+
+        assertThat( invokeMethod( mojo, "existsModuleDescriptor", jdkHome ) )
+            .isEqualTo( false );
+    }
+
+    @Test
     public void shouldShowArray() throws Exception
     {
         Logger logger = mock( Logger.class );
@@ -512,6 +642,71 @@ public class AbstractSurefireMojoTest
     }
 
     @Test
+    public void shouldCreateStartupConfigWithModularPath() throws Exception
+    {
+        String baseDir = System.getProperty( "user.dir" );
+
+        /*if ( !JAVA_RECENT.atLeast( JAVA_9 ) )
+        {
+            return;
+        }*/
+
+        Mojo mojo = new Mojo();
+
+        // ### BEGIN
+        // we cannot mock private method newStartupConfigWithModularPath() - mocking the data to prevent from errors
+        mojo.setLogger( mock( Logger.class ) );
+        mojo.setUseModulePath( true );
+        setInternalState( mojo, "locationManager", new LocationManager() );
+
+        File jdkHome = new File( System.getProperty( "java.home" ) );
+        File jvmExecutable = new File( jdkHome, IS_OS_WINDOWS ? "bin\\java.exe" : "bin/java" );
+        JdkAttributes jdkAttributes = new JdkAttributes( jvmExecutable, jdkHome, true );
+        Platform platform = new Platform().withJdkExecAttributesForTests( jdkAttributes );
+
+        File classesDirectory = new File( baseDir, "mock-dir" );
+        File testClassesDirectory = new File( baseDir, "mock-dir" );
+        TestClassPath testClassPath = new TestClassPath( Collections.<Artifact>emptySet(),
+            classesDirectory, testClassesDirectory, new String[0] );
+
+        ProviderInfo providerInfo = mock( ProviderInfo.class );
+        when( providerInfo.getProviderName() ).thenReturn( "provider mock" );
+        when( providerInfo.getProviderClasspath() ).thenReturn( Collections.<Artifact>emptySet() );
+
+        DefaultScanResult defaultScanResult = mock( DefaultScanResult.class );
+        when( defaultScanResult.getClasses() ).thenReturn( Collections.<String>emptyList() );
+
+        Path pathToModularDescriptor =
+            Paths.get( baseDir, "src", "test", "resources", "org", "apache", "maven", "plugin", "surefire" );
+        mojo.setMainBuildPath( pathToModularDescriptor.toFile() );
+
+        Map<String, Artifact> artifacts = new HashMap<>();
+        Artifact dummyArtifact = mock( Artifact.class );
+        when( dummyArtifact.getFile() ).thenReturn( new File( baseDir, "mock-file" ) );
+        artifacts.put( "org.apache.maven.surefire:maven-surefire-common", dummyArtifact );
+        artifacts.put( "org.apache.maven.surefire:surefire-extensions-api", dummyArtifact );
+        artifacts.put( "org.apache.maven.surefire:surefire-api", dummyArtifact );
+        artifacts.put( "org.apache.maven.surefire:surefire-logger-api", dummyArtifact );
+        artifacts.put( "org.apache.maven.surefire:surefire-extensions-spi", dummyArtifact );
+        artifacts.put( "org.apache.maven.surefire:surefire-booter", dummyArtifact );
+        artifacts.put( "org.apache.maven.surefire:surefire-shared-utils", dummyArtifact );
+        mojo.setPluginArtifactMap( artifacts );
+        // ### END
+
+        StartupConfiguration actualConfig = invokeMethod( mojo, "createStartupConfiguration",
+            new Class[] {ProviderInfo.class, boolean.class, ClassLoaderConfiguration.class, DefaultScanResult.class,
+                Platform.class, TestClassPath.class},
+            providerInfo, true, mock( ClassLoaderConfiguration.class ), defaultScanResult,
+            platform, testClassPath );
+
+        assertThat( actualConfig )
+            .isNotNull();
+
+        assertThat( actualConfig.getClasspathConfiguration() )
+            .isInstanceOf( ModularClasspathConfiguration.class );
+    }
+
+    @Test
     public void shouldExistTmpDirectory() throws IOException
     {
         String systemTmpDir = System.getProperty( "java.io.tmpdir" );
@@ -1804,6 +1999,9 @@ public class AbstractSurefireMojoTest
     public static class Mojo
             extends AbstractSurefireMojo implements SurefireReportParameters
     {
+        private File mainBuildPath;
+        private boolean useModulePath;
+
         private JUnitPlatformProviderInfo createJUnitPlatformProviderInfo( Artifact junitPlatformArtifact,
                                                                            TestClassPath testClasspathWrapper )
         {
@@ -1903,13 +2101,13 @@ public class AbstractSurefireMojoTest
         @Override
         public File getMainBuildPath()
         {
-            return null;
+            return mainBuildPath;
         }
 
         @Override
         public void setMainBuildPath( File mainBuildPath )
         {
-
+            this.mainBuildPath = mainBuildPath;
         }
 
         @Override
@@ -2185,13 +2383,13 @@ public class AbstractSurefireMojoTest
         @Override
         protected boolean useModulePath()
         {
-            return false;
+            return useModulePath;
         }
 
         @Override
         protected void setUseModulePath( boolean useModulePath )
         {
-
+            this.useModulePath = useModulePath;
         }
 
         @Override
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoToolchainsTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoToolchainsTest.java
index 64437fb..ddcb169 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoToolchainsTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoToolchainsTest.java
@@ -37,6 +37,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import static java.io.File.separatorChar;
 import static java.util.Collections.emptyMap;
 import static java.util.Collections.singletonList;
 import static java.util.Collections.singletonMap;
@@ -155,7 +156,8 @@ public class AbstractSurefireMojoToolchainsTest
         assertThat( mojo.getEnvironmentVariables() ).isEmpty();
         JdkAttributes effectiveJvm = invokeMethod( mojo, "getEffectiveJvm" );
         assertThat( mojo.getEnvironmentVariables() ).includes( MapAssert.entry( "JAVA_HOME", "/some/path" ) );
-        assertThat( effectiveJvm.getJvmExecutable() ).contains( "/path/from/toolchain" );
+        assertThat( effectiveJvm.getJvmExecutable().getPath() )
+            .contains( "/path/from/toolchain".replace( '/', separatorChar ) );
     }
 
     @Test
@@ -171,7 +173,8 @@ public class AbstractSurefireMojoToolchainsTest
 
         JdkAttributes effectiveJvm = invokeMethod( mojo, "getEffectiveJvm" );
         assertThat( mojo.getEnvironmentVariables() ).includes( MapAssert.entry( "JAVA_HOME", "/already/set/path" ) );
-        assertThat( effectiveJvm.getJvmExecutable() ).contains( "/path/from/toolchain" );
+        assertThat( effectiveJvm.getJvmExecutable().getPath() )
+            .contains( "/path/from/toolchain".replace( '/', separatorChar ) );
     }
 
     /**
@@ -191,9 +194,9 @@ public class AbstractSurefireMojoToolchainsTest
 
         assertThat( mojo.getEnvironmentVariables() ).isEmpty();
         JdkAttributes effectiveJvm = invokeMethod( mojo, "getEffectiveJvm" );
-        assertThat( mojo.getEnvironmentVariables() ).
-            includes( MapAssert.entry( "JAVA_HOME", currentJdkHome.getAbsolutePath() ) );
-        assertThat( effectiveJvm.getJvmExecutable() ).contains( javaExecutablePath );
+        assertThat( mojo.getEnvironmentVariables() )
+            .includes( MapAssert.entry( "JAVA_HOME", currentJdkHome.getAbsolutePath() ) );
+        assertThat( effectiveJvm.getJvmExecutable().getPath() ).contains( javaExecutablePath );
     }
 
     /**
@@ -207,15 +210,14 @@ public class AbstractSurefireMojoToolchainsTest
         mojo.setEnvironmentVariables( singletonMap( "JAVA_HOME", "/already/set/path" ) );
 
         File currentJdkHome = toJdkHomeFromJre();
-        String javaExecutablePath = FilenameUtils.concat(
-            currentJdkHome.getAbsolutePath(), "bin/java" );
+        String javaExecutablePath = FilenameUtils.concat( currentJdkHome.getAbsolutePath(), "bin/java" );
 
         mojo.setJvm( javaExecutablePath );
 
         JdkAttributes effectiveJvm = invokeMethod( mojo, "getEffectiveJvm" );
-        assertThat( mojo.getEnvironmentVariables() ).
-            includes( MapAssert.entry( "JAVA_HOME", "/already/set/path" ) );
-        assertThat( effectiveJvm.getJvmExecutable() ).contains( javaExecutablePath );
+        assertThat( mojo.getEnvironmentVariables() )
+            .includes( MapAssert.entry( "JAVA_HOME", "/already/set/path" ) );
+        assertThat( effectiveJvm.getJvmExecutable().getPath() ).contains( javaExecutablePath );
     }
 
 
diff --git a/maven-surefire-common/src/test/resources/org/apache/maven/plugin/surefire/module-info.class b/maven-surefire-common/src/test/resources/org/apache/maven/plugin/surefire/module-info.class
new file mode 100644
index 0000000..51e6dcd
Binary files /dev/null and b/maven-surefire-common/src/test/resources/org/apache/maven/plugin/surefire/module-info.class differ