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 2018/05/05 22:33:07 UTC

[maven-surefire] 01/01: [SUREFIRE-1383] dependenciesToScan Does Not Leverage Classpath Elements

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

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

commit 0452ec73c8e46c96619e89a16e1d463c43081198
Author: Tibor17 <ti...@apache.org>
AuthorDate: Sun May 6 00:32:49 2018 +0200

    [SUREFIRE-1383] dependenciesToScan Does Not Leverage Classpath Elements
---
 .../plugin/surefire/AbstractSurefireMojo.java      |  53 +-
 .../plugin/surefire/util/DependencyScanner.java    |  50 +-
 .../maven/plugin/surefire/util/ScannerUtil.java    |   5 +
 .../maven/plugin/surefire/MojoMocklessTest.java    | 625 +++++++++++++++++++++
 .../surefire/util/DependenciesScannerTest.java     |   9 +-
 .../plugin/surefire/util/ScannerUtilTest.java}     |  38 +-
 .../org/apache/maven/surefire/JUnit4SuiteTest.java |   4 +
 .../maven/surefire/booter/SystemUtilsTest.java     |   4 +-
 .../Surefire1383ScanSessionDependenciesIT.java     |  42 +-
 .../src/test/resources/surefire-1383/pom.xml       |  45 ++
 .../test/resources/surefire-1383/runner/pom.xml    |  39 ++
 .../src/main/java/pkg/DynamicRunningTest.java      |  30 +-
 .../src/test/resources/surefire-1383/sut/pom.xml   |  56 ++
 .../apache/maven/surefire/junitcore/TestSet.java   |   8 +-
 14 files changed, 904 insertions(+), 104 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 34f805a..d99cbac 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
@@ -115,9 +115,11 @@ import java.util.concurrent.ConcurrentHashMap;
 import static java.lang.Thread.currentThread;
 import static java.util.Arrays.asList;
 import static java.util.Collections.addAll;
+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.plugin.surefire.util.DependencyScanner.filter;
 import static org.apache.maven.shared.utils.StringUtils.capitalizeFirstLetter;
 import static org.apache.maven.shared.utils.StringUtils.isEmpty;
 import static org.apache.maven.shared.utils.StringUtils.isNotBlank;
@@ -731,8 +733,11 @@ public abstract class AbstractSurefireMojo
      * List of dependencies to scan for test classes to include in the test run.
      * The child elements of this element must be &lt;dependency&gt; elements, and the
      * contents of each of these elements must be a string which follows the format:
-     *
+     * <br>
      * <i>groupId:artifactId</i>. For example: <i>org.acme:project-a</i>.
+     * <br>
+     * Since version 2.22.0 you can scan for test classes from a project
+     * dependency of your multi-module project.
      *
      * @since 2.15
      */
@@ -894,7 +899,13 @@ public abstract class AbstractSurefireMojo
         return scanner.scan();
     }
 
-    private DefaultScanResult scanDependencies()
+    @SuppressWarnings( "unchecked" )
+    List<Artifact> getProjectTestArtifacts()
+    {
+        return project.getTestArtifacts();
+    }
+
+    DefaultScanResult scanDependencies() throws MojoFailureException
     {
         if ( getDependenciesToScan() == null )
         {
@@ -904,16 +915,40 @@ public abstract class AbstractSurefireMojo
         {
             try
             {
-                // @TODO noinspection unchecked, check MavenProject 3.x for Generics in surefire:3.0
-                @SuppressWarnings( "unchecked" )
-                List<File> dependenciesToScan =
-                    DependencyScanner.filter( project.getTestArtifacts(), asList( getDependenciesToScan() ) );
-                DependencyScanner scanner = new DependencyScanner( dependenciesToScan, getIncludedAndExcludedTests() );
-                return scanner.scan();
+                DefaultScanResult result = null;
+
+                List<Artifact> dependenciesToScan =
+                        filter( getProjectTestArtifacts(), asList( getDependenciesToScan() ) );
+
+                for ( Artifact artifact : dependenciesToScan )
+                {
+                    String type = artifact.getType();
+                    File out = artifact.getFile();
+                    if ( out == null || !out.exists()
+                            || !( "jar".equals( type ) || out.isDirectory() || out.getName().endsWith( ".jar" ) ) )
+                    {
+                        continue;
+                    }
+
+                    if ( out.isFile() )
+                    {
+                        DependencyScanner scanner =
+                                new DependencyScanner( singletonList( out ), getIncludedAndExcludedTests() );
+                        result = result == null ? scanner.scan() : result.append( scanner.scan() );
+                    }
+                    else if ( out.isDirectory() )
+                    {
+                        DirectoryScanner scanner =
+                                new DirectoryScanner( out, getIncludedAndExcludedTests() );
+                        result = result == null ? scanner.scan() : result.append( scanner.scan() );
+                    }
+                }
+
+                return result;
             }
             catch ( Exception e )
             {
-                throw new RuntimeException( e );
+                throw new MojoFailureException( e.getLocalizedMessage(), e );
             }
         }
     }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
index 9faf8e6..5f76433 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
@@ -20,6 +20,7 @@ package org.apache.maven.plugin.surefire.util;
  */
 
 import static org.apache.maven.plugin.surefire.util.ScannerUtil.convertJarFileResourceToJavaClassName;
+import static org.apache.maven.plugin.surefire.util.ScannerUtil.isJavaClassFile;
 
 import java.io.File;
 import java.io.IOException;
@@ -60,13 +61,16 @@ public class DependencyScanner
         Set<String> classes = new LinkedHashSet<String>();
         for ( File artifact : dependenciesToScan )
         {
-            try
+            if ( artifact != null && artifact.isFile() && artifact.getName().endsWith( ".jar" ) )
             {
-                scanArtifact( artifact, filter, classes );
-            }
-            catch ( IOException e )
-            {
-                throw new MojoExecutionException( "Could not scan dependency " + artifact.toString(), e );
+                try
+                {
+                    scanArtifact( artifact, filter, classes );
+                }
+                catch ( IOException e )
+                {
+                    throw new MojoExecutionException( "Could not scan dependency " + artifact.toString(), e );
+                }
             }
         }
         return new DefaultScanResult( new ArrayList<String>( classes ) );
@@ -75,34 +79,32 @@ public class DependencyScanner
     private static void scanArtifact( File artifact, TestFilter<String, String> filter, Set<String> classes )
         throws IOException
     {
-        if ( artifact != null && artifact.isFile() )
+        JarFile jar = null;
+        try
         {
-            JarFile jar = null;
-            try
+            jar = new JarFile( artifact );
+            for ( Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); )
             {
-                jar = new JarFile( artifact );
-                for ( Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); )
+                JarEntry entry = entries.nextElement();
+                String path = entry.getName();
+                if ( !entry.isDirectory() && isJavaClassFile( path ) && filter.shouldRun( path, null ) )
                 {
-                    JarEntry entry = entries.nextElement();
-                    if ( filter.shouldRun( entry.getName(), null ) )
-                    {
-                        classes.add( convertJarFileResourceToJavaClassName( entry.getName() ) );
-                    }
+                    classes.add( convertJarFileResourceToJavaClassName( path ) );
                 }
             }
-            finally
+        }
+        finally
+        {
+            if ( jar != null )
             {
-                if ( jar != null )
-                {
-                    jar.close();
-                }
+                jar.close();
             }
         }
     }
 
-    public static List<File> filter( List<Artifact> artifacts, List<String> groupArtifactIds )
+    public static List<Artifact> filter( List<Artifact> artifacts, List<String> groupArtifactIds )
     {
-        List<File> matches = new ArrayList<File>();
+        List<Artifact> matches = new ArrayList<Artifact>();
         if ( groupArtifactIds == null || artifacts == null )
         {
             return matches;
@@ -120,7 +122,7 @@ public class DependencyScanner
                 if ( artifact.getGroupId().matches( groupArtifact[0] )
                     && artifact.getArtifactId().matches( groupArtifact[1] ) )
                 {
-                    matches.add( artifact.getFile() );
+                    matches.add( artifact );
                 }
             }
         }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
index 9989176..8073907 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
@@ -41,6 +41,11 @@ final class ScannerUtil
         return StringUtils.removeEnd( test, ".class" ).replace( "/", "." );
     }
 
+    public static boolean isJavaClassFile( String file )
+    {
+        return file.endsWith( ".class" );
+    }
+
     @Deprecated
     @Nonnull public static String convertSlashToSystemFileSeparator( @Nonnull String path )
     {
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
new file mode 100644
index 0000000..91589a2
--- /dev/null
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
@@ -0,0 +1,625 @@
+package org.apache.maven.plugin.surefire;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.surefire.suite.RunResult;
+import org.apache.maven.surefire.util.DefaultScanResult;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class MojoMocklessTest
+{
+    @Test
+    public void scanDependenciesShouldReturnNull()
+            throws MojoFailureException
+    {
+        Mojo mojo = new Mojo( null, null );
+        DefaultScanResult result = mojo.scanDependencies();
+        assertThat( result )
+                .isNull();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnNullAfterMissingBuildArtifact()
+            throws MojoFailureException
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "jar", null, handler );
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+        assertThat( result )
+                .isNull();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnNullWithWAR()
+            throws MojoFailureException
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "war", null, handler );
+        testDeps.setFile( new File( new File( "target" ), "a-1.0.war" ) );
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+        assertThat( result )
+                .isNull();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnNullWithExistingWAR()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "war", null, handler );
+        File artifactFile = File.createTempFile( "surefire", ".war" );
+        testDeps.setFile( artifactFile );
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+        assertThat( result )
+                .isNull();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnClassWithExistingTestJAR()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "test-jar", null, handler );
+
+        File artifactFile = File.createTempFile( "surefire", ".jar" );
+        testDeps.setFile( artifactFile );
+        ZipOutputStream os = new ZipOutputStream( new FileOutputStream( artifactFile ) );
+        os.putNextEntry( new ZipEntry( "pkg/" ) );
+        os.closeEntry();
+        os.putNextEntry( new ZipEntry( "pkg/MyTest.class" ) );
+        os.closeEntry();
+        os.finish();
+        os.close();
+
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+
+        assertThat( result )
+                .isNotNull();
+
+        assertThat( result.isEmpty() )
+                .isFalse();
+
+        assertThat( result.getClasses() )
+                .contains( "pkg.MyTest" );
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnNullWithEmptyTestJAR()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "jar", null, handler );
+
+        File artifactFile = File.createTempFile( "surefire", ".jar" );
+        testDeps.setFile( artifactFile );
+        ZipOutputStream os = new ZipOutputStream( new FileOutputStream( artifactFile ) );
+        os.putNextEntry( new ZipEntry( "pkg/" ) );
+        os.closeEntry();
+        os.finish();
+        os.close();
+
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+
+        assertThat( result )
+                .isNotNull();
+
+        assertThat( result.isEmpty() )
+                .isTrue();
+    }
+
+    @Test
+    public void scanDependenciesShouldReturnClassWithDirectory()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDeps = new DefaultArtifact( "g", "a", version, "compile", "test-jar", null, handler );
+
+        File artifactFile = File.createTempFile( "surefire", "-classes" );
+        String classDir = artifactFile.getCanonicalPath();
+        assertThat( artifactFile.delete() ).isTrue();
+        File classes = new File( classDir );
+        assertThat( classes.mkdir() ).isTrue();
+
+        testDeps.setFile( classes );
+
+        assertThat( new File( classes, "AnotherTest.class" ).createNewFile() )
+                .isTrue();
+
+        List<Artifact> projectTestArtifacts = singletonList( testDeps );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+
+        assertThat( result )
+                .isNotNull();
+
+        assertThat( result.isEmpty() )
+                .isFalse();
+
+        assertThat( result.getClasses() )
+                .contains( "AnotherTest" );
+    }
+
+    @Test
+    public void scanMultipleDependencies()
+            throws Exception
+    {
+        VersionRange version = VersionRange.createFromVersion( "1.0" );
+        ArtifactHandler handler = new DefaultArtifactHandler();
+        Artifact testDep1 = new DefaultArtifact( "g", "x", version, "compile", "jar", null, handler );
+
+        File artifactFile1 = File.createTempFile( "surefire", "-classes" );
+        String classDir = artifactFile1.getCanonicalPath();
+        assertThat( artifactFile1.delete() ).isTrue();
+        File classes = new File( classDir );
+        assertThat( classes.mkdir() ).isTrue();
+
+        testDep1.setFile( classes );
+
+        assertThat( new File( classes, "AnotherTest.class" ).createNewFile() )
+                .isTrue();
+
+        Artifact testDep2 = new DefaultArtifact( "g", "a", version, "test", "jar", null, handler );
+        File artifactFile2 = File.createTempFile( "surefire", ".jar" );
+        testDep2.setFile( artifactFile2 );
+        ZipOutputStream os = new ZipOutputStream( new FileOutputStream( artifactFile2 ) );
+        os.putNextEntry( new ZipEntry( "pkg/" ) );
+        os.closeEntry();
+        os.putNextEntry( new ZipEntry( "pkg/MyTest.class" ) );
+        os.closeEntry();
+        os.finish();
+        os.close();
+
+        List<Artifact> projectTestArtifacts = asList( testDep1, testDep2 );
+        String[] dependenciesToScan = { "g:a" };
+        Mojo mojo = new Mojo( projectTestArtifacts, dependenciesToScan );
+        DefaultScanResult result = mojo.scanDependencies();
+
+        assertThat( result )
+                .isNotNull();
+
+        assertThat( result.isEmpty() )
+                .isFalse();
+
+        assertThat( result.getClasses() )
+                .hasSize( 1 );
+
+        assertThat( result.getClasses() )
+                .contains( "pkg.MyTest" );
+    }
+
+    private final static class Mojo
+            extends AbstractSurefireMojo
+    {
+        private final List<Artifact> projectTestArtifacts;
+        private final String[] dependenciesToScan;
+
+        Mojo( List<Artifact> projectTestArtifacts, String[] dependenciesToScan )
+        {
+            this.projectTestArtifacts = projectTestArtifacts;
+            this.dependenciesToScan = dependenciesToScan;
+        }
+
+        @Override
+        protected String getPluginName()
+        {
+            return null;
+        }
+
+        @Override
+        protected int getRerunFailingTestsCount()
+        {
+            return 0;
+        }
+
+        @Override
+        public boolean isSkipTests()
+        {
+            return false;
+        }
+
+        @Override
+        public void setSkipTests( boolean skipTests )
+        {
+
+        }
+
+        @Override
+        public boolean isSkipExec()
+        {
+            return false;
+        }
+
+        @Override
+        public void setSkipExec( boolean skipExec )
+        {
+
+        }
+
+        @Override
+        public boolean isSkip()
+        {
+            return false;
+        }
+
+        @Override
+        public void setSkip( boolean skip )
+        {
+
+        }
+
+        @Override
+        public File getBasedir()
+        {
+            return null;
+        }
+
+        @Override
+        public void setBasedir( File basedir )
+        {
+
+        }
+
+        @Override
+        public File getTestClassesDirectory()
+        {
+            return null;
+        }
+
+        @Override
+        public void setTestClassesDirectory( File testClassesDirectory )
+        {
+
+        }
+
+        @Override
+        public File getClassesDirectory()
+        {
+            return null;
+        }
+
+        @Override
+        public void setClassesDirectory( File classesDirectory )
+        {
+
+        }
+
+        @Override
+        public File getReportsDirectory()
+        {
+            return null;
+        }
+
+        @Override
+        public void setReportsDirectory( File reportsDirectory )
+        {
+
+        }
+
+        @Override
+        public String getTest()
+        {
+            return null;
+        }
+
+        @Override
+        public void setTest( String test )
+        {
+
+        }
+
+        @Override
+        public List<String> getIncludes()
+        {
+            return null;
+        }
+
+        @Override
+        public File getIncludesFile()
+        {
+            return null;
+        }
+
+        @Override
+        public void setIncludes( List<String> includes )
+        {
+
+        }
+
+        @Override
+        public boolean isPrintSummary()
+        {
+            return false;
+        }
+
+        @Override
+        public void setPrintSummary( boolean printSummary )
+        {
+
+        }
+
+        @Override
+        public String getReportFormat()
+        {
+            return null;
+        }
+
+        @Override
+        public void setReportFormat( String reportFormat )
+        {
+
+        }
+
+        @Override
+        public boolean isUseFile()
+        {
+            return false;
+        }
+
+        @Override
+        public void setUseFile( boolean useFile )
+        {
+
+        }
+
+        @Override
+        public String getDebugForkedProcess()
+        {
+            return null;
+        }
+
+        @Override
+        public void setDebugForkedProcess( String debugForkedProcess )
+        {
+
+        }
+
+        @Override
+        public int getForkedProcessTimeoutInSeconds()
+        {
+            return 0;
+        }
+
+        @Override
+        public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
+        {
+
+        }
+
+        @Override
+        public int getForkedProcessExitTimeoutInSeconds()
+        {
+            return 0;
+        }
+
+        @Override
+        public void setForkedProcessExitTimeoutInSeconds( int forkedProcessTerminationTimeoutInSeconds )
+        {
+
+        }
+
+        @Override
+        public double getParallelTestsTimeoutInSeconds()
+        {
+            return 0;
+        }
+
+        @Override
+        public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
+        {
+
+        }
+
+        @Override
+        public double getParallelTestsTimeoutForcedInSeconds()
+        {
+            return 0;
+        }
+
+        @Override
+        public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
+        {
+
+        }
+
+        @Override
+        public boolean isUseSystemClassLoader()
+        {
+            return false;
+        }
+
+        @Override
+        public void setUseSystemClassLoader( boolean useSystemClassLoader )
+        {
+
+        }
+
+        @Override
+        public boolean isUseManifestOnlyJar()
+        {
+            return false;
+        }
+
+        @Override
+        public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
+        {
+
+        }
+
+        @Override
+        public String getEncoding()
+        {
+            return null;
+        }
+
+        @Override
+        public void setEncoding( String encoding )
+        {
+
+        }
+
+        @Override
+        public Boolean getFailIfNoSpecifiedTests()
+        {
+            return null;
+        }
+
+        @Override
+        public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
+        {
+
+        }
+
+        @Override
+        public int getSkipAfterFailureCount()
+        {
+            return 0;
+        }
+
+        @Override
+        public String getShutdown()
+        {
+            return null;
+        }
+
+        @Override
+        public File getExcludesFile()
+        {
+            return null;
+        }
+
+        @Override
+        protected List<File> suiteXmlFiles()
+        {
+            return null;
+        }
+
+        @Override
+        protected boolean hasSuiteXmlFiles()
+        {
+            return false;
+        }
+
+        @Override
+        public File[] getSuiteXmlFiles()
+        {
+            return new File[0];
+        }
+
+        @Override
+        public void setSuiteXmlFiles( File[] suiteXmlFiles )
+        {
+
+        }
+
+        @Override
+        public String getRunOrder()
+        {
+            return null;
+        }
+
+        @Override
+        public void setRunOrder( String runOrder )
+        {
+
+        }
+
+        @Override
+        public String[] getDependenciesToScan()
+        {
+            return dependenciesToScan;
+        }
+
+        @Override
+        protected void handleSummary( RunResult summary, Exception firstForkException )
+                throws MojoExecutionException, MojoFailureException
+        {
+
+        }
+
+        @Override
+        protected boolean isSkipExecution()
+        {
+            return false;
+        }
+
+        @Override
+        protected String[] getDefaultIncludes()
+        {
+            return new String[0];
+        }
+
+        @Override
+        protected String getReportSchemaLocation()
+        {
+            return null;
+        }
+
+        @Override
+        protected Artifact getMojoArtifact()
+        {
+            return null;
+        }
+
+        @Override
+        List<Artifact> getProjectTestArtifacts()
+        {
+            return projectTestArtifacts;
+        }
+    }
+}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
index c8dd436..b9335d6 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
@@ -56,9 +56,14 @@ public class DependenciesScannerTest
         include.add( "**/*A.java" );
         List<String> exclude = new ArrayList<String>();
 
+        List<File> dependenciesToScan = new ArrayList<File>();
+        for ( Artifact a : DependencyScanner.filter( Collections.singletonList( artifact ), scanDependencies ) )
+        {
+            dependenciesToScan.add( a.getFile() );
+        }
+
         DependencyScanner scanner =
-            new DependencyScanner( DependencyScanner.filter( Collections.singletonList( artifact ), scanDependencies ),
-                                   new TestListResolver( include, exclude ) );
+            new DependencyScanner( dependenciesToScan, new TestListResolver( include, exclude ) );
 
         ScanResult classNames = scanner.scan();
         assertNotNull( classNames );
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/ScannerUtilTest.java
similarity index 50%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
copy to maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/ScannerUtilTest.java
index 9989176..066a715 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/ScannerUtilTest.java
@@ -19,31 +19,37 @@ package org.apache.maven.plugin.surefire.util;
  * under the License.
  */
 
-import org.apache.commons.lang3.StringUtils;
-import javax.annotation.Nonnull;
+import org.junit.Test;
 
-final class ScannerUtil
+import static org.fest.assertions.Assertions.assertThat;
+
+/**
+ * Unit test for {@link ScannerUtil}
+ */
+public class ScannerUtilTest
 {
 
-    private ScannerUtil()
+    @Test
+    public void shouldConvertJarFileResourceToJavaClassName()
     {
-        throw new IllegalStateException( "not instantiable constructor" );
-    }
+        String className = ScannerUtil.convertJarFileResourceToJavaClassName( "org/apache/pkg/MyService.class" );
 
-    @Deprecated
-    private static final String FS = System.getProperty( "file.separator" );
+        assertThat( className )
+                .isEqualTo( "org.apache.pkg.MyService" );
 
-    @Deprecated
-    private static final boolean IS_NON_UNIX_FS = ( !FS.equals( "/" ) );
+        className = ScannerUtil.convertJarFileResourceToJavaClassName( "META-INF/MANIFEST.MF" );
 
-    @Nonnull public static String convertJarFileResourceToJavaClassName( @Nonnull String test )
-    {
-        return StringUtils.removeEnd( test, ".class" ).replace( "/", "." );
+        assertThat( className )
+                .isEqualTo( "META-INF.MANIFEST.MF" );
     }
 
-    @Deprecated
-    @Nonnull public static String convertSlashToSystemFileSeparator( @Nonnull String path )
+    @Test
+    public void shouldBeClassFile()
     {
-        return ( IS_NON_UNIX_FS ? path.replace( "/", FS ) : path );
+        assertThat( ScannerUtil.isJavaClassFile( "META-INF/MANIFEST.MF" ) )
+                .isFalse();
+
+        assertThat( ScannerUtil.isJavaClassFile( "org/apache/pkg/MyService.class" ) )
+                .isTrue();
     }
 }
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java b/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
index bd99abc..728cef3 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
@@ -25,6 +25,7 @@ import junit.framework.TestCase;
 import junit.framework.TestSuite;
 import org.apache.maven.plugin.surefire.AbstractSurefireMojoJava7PlusTest;
 import org.apache.maven.plugin.surefire.AbstractSurefireMojoTest;
+import org.apache.maven.plugin.surefire.MojoMocklessTest;
 import org.apache.maven.plugin.surefire.SurefireHelperTest;
 import org.apache.maven.plugin.surefire.SurefireReflectorTest;
 import org.apache.maven.plugin.surefire.SurefirePropertiesTest;
@@ -42,6 +43,7 @@ import org.apache.maven.plugin.surefire.report.WrappedReportEntryTest;
 import org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMapTest;
 import org.apache.maven.plugin.surefire.util.DependenciesScannerTest;
 import org.apache.maven.plugin.surefire.util.DirectoryScannerTest;
+import org.apache.maven.plugin.surefire.util.ScannerUtilTest;
 import org.apache.maven.plugin.surefire.util.SpecificFileFilterTest;
 import org.apache.maven.surefire.report.ConsoleOutputFileReporterTest;
 import org.apache.maven.surefire.report.FileReporterTest;
@@ -91,6 +93,8 @@ public class JUnit4SuiteTest extends TestCase
         {
             suite.addTest( new JUnit4TestAdapter( AbstractSurefireMojoJava7PlusTest.class ) );
         }
+        suite.addTest( new JUnit4TestAdapter( ScannerUtilTest.class ) );
+        suite.addTest( new JUnit4TestAdapter( MojoMocklessTest.class ) );
         return suite;
     }
 }
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
index 5120cb5..a957d06 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java
@@ -299,13 +299,13 @@ public class SystemUtilsTest
     {
 
         @Test
-        public void shouldBeDifferentJdk9() throws IOException
+        public void shouldBeDifferentJdk9()
         {
             testIsJava9AtLeast( new File( System.getProperty( "java.home" ) ) );
         }
 
         @Test
-        public void shouldBeSameJdk9() throws IOException
+        public void shouldBeSameJdk9()
         {
             // PowerMockJUnit44RunnerDelegateImpl does not work with Assumptions: assumeFalse
             if ( !JAVA_RECENT.atLeast( JAVA_9 ) )
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1383ScanSessionDependenciesIT.java
similarity index 50%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
copy to surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1383ScanSessionDependenciesIT.java
index 9989176..b9ea215 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1383ScanSessionDependenciesIT.java
@@ -1,4 +1,4 @@
-package org.apache.maven.plugin.surefire.util;
+package org.apache.maven.surefire.its.jiras;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,31 +19,25 @@ package org.apache.maven.plugin.surefire.util;
  * under the License.
  */
 
-import org.apache.commons.lang3.StringUtils;
-import javax.annotation.Nonnull;
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
+import org.apache.maven.surefire.its.fixture.SurefireLauncher;
+import org.junit.Test;
 
-final class ScannerUtil
+/**
+ * @author <a href="mailto:owen.farrell@gmail.com">Owen Farrell (owenfarrell)</a>
+ * @see <a href="https://issues.apache.org/jira/browse/SUREFIRE-1383">SUREFIRE-1383</a>
+ * @since 2.20.1
+ */
+public class Surefire1383ScanSessionDependenciesIT
+        extends SurefireJUnit4IntegrationTestCase
 {
-
-    private ScannerUtil()
-    {
-        throw new IllegalStateException( "not instantiable constructor" );
-    }
-
-    @Deprecated
-    private static final String FS = System.getProperty( "file.separator" );
-
-    @Deprecated
-    private static final boolean IS_NON_UNIX_FS = ( !FS.equals( "/" ) );
-
-    @Nonnull public static String convertJarFileResourceToJavaClassName( @Nonnull String test )
-    {
-        return StringUtils.removeEnd( test, ".class" ).replace( "/", "." );
-    }
-
-    @Deprecated
-    @Nonnull public static String convertSlashToSystemFileSeparator( @Nonnull String path )
+    @Test
+    public void test() throws VerificationException
     {
-        return ( IS_NON_UNIX_FS ? path.replace( "/", FS ) : path );
+        SurefireLauncher launcher = unpack( "surefire-1383" );
+        launcher.executeTest();
+        launcher.getSubProjectValidator( "sut" )
+                .assertTestSuiteResults( 1, 0, 0, 0 );
     }
 }
diff --git a/surefire-its/src/test/resources/surefire-1383/pom.xml b/surefire-its/src/test/resources/surefire-1383/pom.xml
new file mode 100644
index 0000000..1b4b7c3
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1383/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    
+    <parent>
+        <groupId>org.apache.maven.surefire</groupId>
+        <artifactId>it-parent</artifactId>
+        <version>1.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.apache.maven.plugins.surefire</groupId>
+    <artifactId>surefire-1383</artifactId>
+    <version>1.0</version>
+    <packaging>pom</packaging>
+    <modules>
+        <module>runner</module>
+        <module>sut</module>
+    </modules>
+
+    <properties>
+        <maven.compiler.source>1.5</maven.compiler.source>
+        <maven.compiler.target>1.5</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+</project>
diff --git a/surefire-its/src/test/resources/surefire-1383/runner/pom.xml b/surefire-its/src/test/resources/surefire-1383/runner/pom.xml
new file mode 100644
index 0000000..eaad1a0
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1383/runner/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    
+    <parent>
+        <groupId>org.apache.maven.plugins.surefire</groupId>
+        <artifactId>surefire-1383</artifactId>
+        <version>1.0</version>
+    </parent>
+    
+    <artifactId>surefire-1383-runner</artifactId>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>6.11</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/surefire-its/src/test/resources/surefire-1383/runner/src/main/java/pkg/DynamicRunningTest.java
similarity index 50%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
copy to surefire-its/src/test/resources/surefire-1383/runner/src/main/java/pkg/DynamicRunningTest.java
index 9989176..1b37af5 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
+++ b/surefire-its/src/test/resources/surefire-1383/runner/src/main/java/pkg/DynamicRunningTest.java
@@ -1,5 +1,4 @@
-package org.apache.maven.plugin.surefire.util;
-
+package pkg;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,31 +18,16 @@ package org.apache.maven.plugin.surefire.util;
  * under the License.
  */
 
-import org.apache.commons.lang3.StringUtils;
-import javax.annotation.Nonnull;
+import org.testng.annotations.Test;
 
-final class ScannerUtil
+@Test
+public class DynamicRunningTest
 {
 
-    private ScannerUtil()
-    {
-        throw new IllegalStateException( "not instantiable constructor" );
-    }
-
-    @Deprecated
-    private static final String FS = System.getProperty( "file.separator" );
-
-    @Deprecated
-    private static final boolean IS_NON_UNIX_FS = ( !FS.equals( "/" ) );
-
-    @Nonnull public static String convertJarFileResourceToJavaClassName( @Nonnull String test )
+    public void shouldRun()
     {
-        return StringUtils.removeEnd( test, ".class" ).replace( "/", "." );
+        // Test runners such as this one may dynamically invoke other frameworks such as Cucumber, Selenium, etc.
+        // The actual operation is not relevant to the issue.
     }
 
-    @Deprecated
-    @Nonnull public static String convertSlashToSystemFileSeparator( @Nonnull String path )
-    {
-        return ( IS_NON_UNIX_FS ? path.replace( "/", FS ) : path );
-    }
 }
diff --git a/surefire-its/src/test/resources/surefire-1383/sut/pom.xml b/surefire-its/src/test/resources/surefire-1383/sut/pom.xml
new file mode 100644
index 0000000..2a31ad7
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1383/sut/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    
+    <parent>
+        <groupId>org.apache.maven.plugins.surefire</groupId>
+        <artifactId>surefire-1383</artifactId>
+        <version>1.0</version>
+    </parent>
+    
+    <artifactId>surefire-1383-sut</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>surefire-1383-runner</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${surefire.version}</version>
+                <configuration>
+                    <dependenciesToScan>
+                        <param>${project.groupId}:surefire-1383-runner</param>
+                    </dependenciesToScan>
+                    <failIfNoTests>true</failIfNoTests>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestSet.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestSet.java
index 9371b51..184d32e 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestSet.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestSet.java
@@ -70,13 +70,13 @@ public class TestSet
 
                 target.testSetStarting( report );
 
-                long startTile = 0;
+                long startTime = 0;
                 long endTime = 0;
                 for ( TestMethod testMethod : testMethods )
                 {
-                    if ( startTile == 0 || testMethod.getStartTime() < startTile )
+                    if ( startTime == 0 || testMethod.getStartTime() < startTime )
                     {
-                        startTile = testMethod.getStartTime();
+                        startTime = testMethod.getStartTime();
                     }
 
                     if ( endTime == 0 || testMethod.getEndTime() > endTime )
@@ -87,7 +87,7 @@ public class TestSet
                     testMethod.replay( target );
                 }
 
-                int elapsed = (int) ( endTime - startTile );
+                int elapsed = (int) ( endTime - startTime );
 
                 report = createReportEntryCompleted( elapsed );
 

-- 
To stop receiving notification emails like this one, please contact
tibordigana@apache.org.