Repository: maven-surefire
Updated Branches:
  refs/heads/SUREFIRE-1376 de410132b -> 59c065f5d (forced update)


[SUREFIRE-1376] "The forked VM terminated without properly saying goodbye" when 
running Surefire in a very deep project structure on Windows


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/59c065f5
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/59c065f5
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/59c065f5

Branch: refs/heads/SUREFIRE-1376
Commit: 59c065f5d4a5a9c181ef9ce788b31305886e8592
Parents: fac376c
Author: Tibor17 <tibordig...@apache.org>
Authored: Sat Jun 3 08:55:23 2017 +0200
Committer: Tibor17 <tibordig...@apache.org>
Committed: Sat Jun 3 12:46:46 2017 +0200

----------------------------------------------------------------------
 .../maven/plugin/surefire/SurefireHelper.java   | 33 ++++++++++++++++++++
 .../booterclient/ForkConfiguration.java         | 13 ++++----
 .../plugin/surefire/SurefireHelperTest.java     | 24 ++++++++++++++
 3 files changed, 63 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/59c065f5/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java
 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java
index 8bdf75e..cd49249 100644
--- 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java
+++ 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java
@@ -36,6 +36,7 @@ import java.util.Collection;
 import java.util.List;
 
 import static java.util.Collections.unmodifiableList;
+import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
 import static 
org.apache.maven.surefire.booter.DumpErrorSingleton.DUMPSTREAM_FILE_EXT;
 import static 
org.apache.maven.surefire.booter.DumpErrorSingleton.DUMP_FILE_EXT;
 import static 
org.apache.maven.surefire.cli.CommandLineOption.LOGGING_LEVEL_DEBUG;
@@ -55,6 +56,19 @@ public final class SurefireHelper
 
     public static final String DUMPSTREAM_FILENAME_FORMATTER = 
DUMP_FILE_PREFIX + "%d" + DUMPSTREAM_FILE_EXT;
 
+    /**
+     * see sun/nio/fs/WindowsPath <br>
+     * 
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/7534523b4174/src/windows/classes/sun/nio/fs/WindowsPath.java#l46
+     * https://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
+     * <br>
+     * <br>
+     * The maximum path that does not require long path prefix. On Windows <br>
+     * the maximum path is 260 minus 1 (NUL) but for directories it is 260 <br>
+     * minus 12 minus 1 (to allow for the creation of a 8.3 file in the <br>
+     * directory).
+     */
+    private static final int MAX_PATH_LENGTH_WINDOWS = 247;
+
     private static final String[] DUMP_FILES_PRINT =
             {
                     "[date]-jvmRun[N]" + DUMP_FILE_EXT,
@@ -165,6 +179,25 @@ public final class SurefireHelper
         }
     }
 
+    /**
+     * Normalized file path for Windows; otherwise returns {@code path}.
+     * <br>
+     * 
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/7534523b4174/src/windows/classes/sun/nio/fs/WindowsPath.java#l46
+     * <br>
+     * https://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
+     *
+     * @param path    source path
+     * @return escaped to platform path
+     */
+    public static String escapeToPlatformPath( String path )
+    {
+        if ( IS_OS_WINDOWS && path.length() > MAX_PATH_LENGTH_WINDOWS )
+        {
+            path = path.startsWith( "\\\\" ) ? "\\\\?\\UNC\\" + 
path.substring( 2 ) : "\\\\?\\" + path;
+        }
+        return path;
+    }
+
     private static String getFailureBehavior( MavenExecutionRequest request )
         throws NoSuchMethodException, InvocationTargetException, 
IllegalAccessException
     {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/59c065f5/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
index cd4ae2b..2768210 100644
--- 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
+++ 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
@@ -21,13 +21,13 @@ package org.apache.maven.plugin.surefire.booterclient;
 
 import org.apache.maven.plugin.surefire.AbstractSurefireMojo;
 import 
org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
-import org.apache.maven.surefire.util.internal.ImmutableMap;
 import org.apache.maven.plugin.surefire.util.Relocator;
 import org.apache.maven.shared.utils.StringUtils;
 import org.apache.maven.surefire.booter.Classpath;
 import org.apache.maven.surefire.booter.ForkedBooter;
 import org.apache.maven.surefire.booter.StartupConfiguration;
 import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.util.internal.ImmutableMap;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -41,6 +41,8 @@ import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
 
+import static 
org.apache.maven.plugin.surefire.SurefireHelper.escapeToPlatformPath;
+
 /**
  * Configuration for forking tests.
  *
@@ -174,19 +176,16 @@ public class ForkConfiguration
 
         if ( useJar )
         {
-            File jarFile;
             try
             {
-                jarFile = createJar( classPath, providerThatHasMainMethod );
+                File jarFile = createJar( classPath, providerThatHasMainMethod 
);
+                cli.createArg().setValue( "-jar" );
+                cli.createArg().setValue( escapeToPlatformPath( 
jarFile.getAbsolutePath() ) );
             }
             catch ( IOException e )
             {
                 throw new SurefireBooterForkException( "Error creating archive 
file", e );
             }
-
-            cli.createArg().setValue( "-jar" );
-
-            cli.createArg().setValue( jarFile.getAbsolutePath() );
         }
         else
         {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/59c065f5/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java
 
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java
index b249aca..c00f7f9 100644
--- 
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java
+++ 
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java
@@ -26,7 +26,10 @@ import java.util.List;
 
 import static java.util.Collections.addAll;
 import static java.util.Collections.singleton;
+import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
+import static 
org.apache.maven.plugin.surefire.SurefireHelper.escapeToPlatformPath;
 import static org.fest.assertions.Assertions.assertThat;
+import static org.junit.Assume.assumeTrue;
 
 /**
  * Test of {@link SurefireHelper}.
@@ -62,4 +65,25 @@ public class SurefireHelperTest
         assertThat( String.format( 
SurefireHelper.DUMPSTREAM_FILENAME_FORMATTER, 5) )
                 .endsWith( "-jvmRun5.dumpstream" );
     }
+
+    @Test
+    public void shouldEscapeWindowsPath()
+    {
+        assumeTrue( IS_OS_WINDOWS );
+        String root = "X:\\path\\to\\project\\";
+        String pathToJar = 
"target\\surefire\\surefirebooter4942721306300108667.jar";
+        int projectNameLength = 247 - root.length() - pathToJar.length();
+        StringBuilder projectFolder = new StringBuilder();
+        for ( int i = 0; i < projectNameLength; i++ )
+        {
+            projectFolder.append( 'x' );
+        }
+        String path = root + projectFolder + "\\" + pathToJar;
+        String escaped = escapeToPlatformPath( path );
+        assertThat( escaped ).isEqualTo( "\\\\?\\" + path );
+
+        path = root + "\\" + pathToJar;
+        escaped = escapeToPlatformPath( path );
+        assertThat( escaped ).isEqualTo( root + "\\" + pathToJar );
+    }
 }

Reply via email to