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 2016/10/13 19:31:03 UTC

[02/25] maven-surefire git commit: [SUREFIRE-1246] Surefire + Cobertura: Shutdown of Forked JVM timeouts before all thread ends

[SUREFIRE-1246] Surefire + Cobertura: Shutdown of Forked JVM timeouts before all thread ends


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

Branch: refs/heads/junit5
Commit: 2c6105c5e5a1d148e2edcbc385bb2ed66969e667
Parents: 61c7257
Author: Tibor17 <ti...@lycos.com>
Authored: Sat Sep 24 10:30:30 2016 +0200
Committer: Tibor17 <ti...@lycos.com>
Committed: Sat Sep 24 10:38:17 2016 +0200

----------------------------------------------------------------------
 .../plugin/failsafe/IntegrationTestMojo.java    | 22 ++++++++++++++++++++
 .../plugin/surefire/AbstractSurefireMojo.java   |  3 ++-
 .../surefire/SurefireExecutionParameters.java   |  4 ++++
 .../surefire/booterclient/BooterSerializer.java |  4 +++-
 ...erDeserializerProviderConfigurationTest.java |  2 +-
 ...terDeserializerStartupConfigurationTest.java |  2 +-
 .../maven/plugin/surefire/SurefirePlugin.java   | 22 ++++++++++++++++++++
 .../src/site/apt/examples/shutdown.apt.vm       |  3 ++-
 .../surefire/booter/BaseProviderFactory.java    | 12 +++++++++++
 .../surefire/booter/SurefireReflector.java      | 12 +++++------
 .../providerapi/ProviderParameters.java         |  2 ++
 .../maven/surefire/booter/BooterConstants.java  |  1 +
 .../surefire/booter/BooterDeserializer.java     |  7 ++++++-
 .../maven/surefire/booter/ForkedBooter.java     | 16 +++++++-------
 .../surefire/booter/ProviderConfiguration.java  | 19 ++++++++++++++---
 .../maven/surefire/booter/ProviderFactory.java  |  5 ++++-
 16 files changed, 112 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
----------------------------------------------------------------------
diff --git a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
index 78a3cd7..9f30534 100644
--- a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
+++ b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
@@ -154,6 +154,18 @@ public class IntegrationTestMojo
     private int forkedProcessTimeoutInSeconds;
 
     /**
+     * Forked process is normally terminated without any significant delay after given tests have completed.
+     * If the particular tests started non-daemon Thread(s), the process hangs instead of been properly terminated
+     * by <em>System.exit()</em>. Use this parameter in order to determine the timeout of terminating the process.
+     * <a href="http://maven.apache.org/surefire/maven-failsafe-plugin/examples/shutdown.html">see the documentation:
+     * http://maven.apache.org/surefire/maven-failsafe-plugin/examples/shutdown.html</a>
+     *
+     * @since 2.19.2
+     */
+    @Parameter( property = "failsafe.exitTimeout", defaultValue = "30" )
+    private int forkedProcessExitTimeoutInSeconds;
+
+    /**
      * Stop executing queued parallel JUnit tests after a certain number of seconds.
      * <br/>
      * Example values: "3.5", "4"<br/>
@@ -563,6 +575,16 @@ public class IntegrationTestMojo
         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
     }
 
+    public int getForkedProcessExitTimeoutInSeconds()
+    {
+        return forkedProcessExitTimeoutInSeconds;
+    }
+
+    public void setForkedProcessExitTimeoutInSeconds( int forkedProcessExitTimeoutInSeconds )
+    {
+        this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds;
+    }
+
     public double getParallelTestsTimeoutInSeconds()
     {
         return parallelTestsTimeoutInSeconds;

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
----------------------------------------------------------------------
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 cd27edf..5e22b70 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
@@ -1543,7 +1543,8 @@ public abstract class AbstractSurefireMojo
                                           testNg, // Not really used in provider. Limited to de/serializer.
                                           testSuiteDefinition, providerProperties, null,
                                           false, cli, getSkipAfterFailureCount(),
-                                          Shutdown.parameterOf( getShutdown() ) );
+                                          Shutdown.parameterOf( getShutdown() ),
+                                          getForkedProcessExitTimeoutInSeconds() );
     }
 
     private static Map<String, String> toStringProperties( Properties properties )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java
index 247f5e8..96fb09e 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java
@@ -99,6 +99,10 @@ public interface SurefireExecutionParameters
 
     void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds );
 
+    int getForkedProcessExitTimeoutInSeconds();
+
+    void setForkedProcessExitTimeoutInSeconds( int forkedProcessTerminationTimeoutInSeconds );
+
     double getParallelTestsTimeoutInSeconds();
 
     void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
index e67efb0..2aac04b 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
@@ -139,11 +139,13 @@ class BooterSerializer
             properties.addList( mainCliOptions, MAIN_CLI_OPTIONS );
         }
 
+        properties.setNullableProperty( SYSTEM_EXIT_TIMEOUT,
+                                              String.valueOf( booterConfiguration.getSystemExitTimeout() ) );
+
         return SystemPropertyManager.writePropertiesFile( properties, forkConfiguration.getTempDirectory(),
                                                           "surefire", forkConfiguration.isDebug() );
     }
 
-
     private String getTypeEncoded( Object value )
     {
         if ( value == null )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java
index 623edf3..6759367 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java
@@ -237,7 +237,7 @@ public class BooterDeserializerProviderConfigurationTest
         RunOrderParameters runOrderParameters = new RunOrderParameters( RunOrder.DEFAULT, null );
         return new ProviderConfiguration( directoryScannerParameters, runOrderParameters, true, reporterConfiguration,
                 new TestArtifactInfo( "5.0", "ABC" ), testSuiteDefinition, new HashMap<String, String>(), aTestTyped,
-                readTestsFromInStream, cli, 0, Shutdown.DEFAULT );
+                readTestsFromInStream, cli, 0, Shutdown.DEFAULT, 0 );
     }
 
     private StartupConfiguration getTestStartupConfiguration( ClassLoaderConfiguration classLoaderConfiguration )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
index 007640d..1ca20d2 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
@@ -144,7 +144,7 @@ public class BooterDeserializerStartupConfigurationTest
         RunOrderParameters runOrderParameters = new RunOrderParameters( RunOrder.DEFAULT, null );
         return new ProviderConfiguration( directoryScannerParameters, runOrderParameters, true, reporterConfiguration,
                 new TestArtifactInfo( "5.0", "ABC" ), testSuiteDefinition, new HashMap<String, String>(),
-                BooterDeserializerProviderConfigurationTest.aTestTyped, true, cli, 0, Shutdown.DEFAULT );
+                BooterDeserializerProviderConfigurationTest.aTestTyped, true, cli, 0, Shutdown.DEFAULT, 0 );
     }
 
     private StartupConfiguration getTestStartupConfiguration( ClassLoaderConfiguration classLoaderConfiguration )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
----------------------------------------------------------------------
diff --git a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
index bfb68e0..f508372 100644
--- a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
+++ b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
@@ -138,6 +138,18 @@ public class SurefirePlugin
     private int forkedProcessTimeoutInSeconds;
 
     /**
+     * Forked process is normally terminated without any significant delay after given tests have completed.
+     * If the particular tests started non-daemon Thread(s), the process hangs instead of been properly terminated
+     * by <em>System.exit()</em>. Use this parameter in order to determine the timeout of terminating the process.
+     * <a href="http://maven.apache.org/surefire/maven-surefire-plugin/examples/shutdown.html">see the documentation:
+     * http://maven.apache.org/surefire/maven-surefire-plugin/examples/shutdown.html</a>
+     *
+     * @since 2.19.2
+     */
+    @Parameter( property = "surefire.exitTimeout", defaultValue = "30" )
+    private int forkedProcessExitTimeoutInSeconds;
+
+    /**
      * Stop executing queued parallel JUnit tests after a certain number of seconds.
      * <br/>
      * Example values: "3.5", "4"<br/>
@@ -536,6 +548,16 @@ public class SurefirePlugin
         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
     }
 
+    public int getForkedProcessExitTimeoutInSeconds()
+    {
+        return forkedProcessExitTimeoutInSeconds;
+    }
+
+    public void setForkedProcessExitTimeoutInSeconds( int forkedProcessExitTimeoutInSeconds )
+    {
+        this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds;
+    }
+
     public double getParallelTestsTimeoutInSeconds()
     {
         return parallelTestsTimeoutInSeconds;

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm
----------------------------------------------------------------------
diff --git a/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm b/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm
index b9c3fd3..7e943a5 100644
--- a/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/shutdown.apt.vm
@@ -34,7 +34,8 @@ Shutdown of Forked JVM
   <<<java.lang.System.exit(0)>>> which starts shutdown hooks. At this point
   the process may run next 30 seconds until all non daemon Threads die.
   After the period of time has elapsed, the process kills itself by
-  <<<java.lang.Runtime.halt(0)>>>.
+  <<<java.lang.Runtime.halt(0)>>>. The timeout of 30 seconds can be
+  customized by configuration parameter <<<forkedProcessExitTimeoutInSeconds>>>.
 
 * Pinging forked JVM
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java
index 66f28ad..2a713ef 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java
@@ -77,6 +77,8 @@ public class BaseProviderFactory
 
     private Shutdown shutdown;
 
+    private Integer systemExitTimeout;
+
     public BaseProviderFactory( ReporterFactory reporterFactory, boolean insideFork )
     {
         this.reporterFactory = reporterFactory;
@@ -221,4 +223,14 @@ public class BaseProviderFactory
     {
         this.shutdown = shutdown;
     }
+
+    public Integer getSystemExitTimeout()
+    {
+        return systemExitTimeout;
+    }
+
+    public void setSystemExitTimeout( Integer systemExitTimeout )
+    {
+        this.systemExitTimeout = systemExitTimeout;
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
index b25c04b..958a23a 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
@@ -20,7 +20,6 @@ package org.apache.maven.surefire.booter;
  */
 
 import java.io.File;
-import java.io.PrintStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
@@ -261,12 +260,6 @@ public class SurefireReflector
         return newInstance( constructor, reporterConfig.getReportsDirectory(), reporterConfig.isTrimStackTrace() );
     }
 
-    public static ReporterFactory createForkingReporterFactoryInCurrentClassLoader( boolean trimStackTrace,
-                                                                                    PrintStream originalSystemOut )
-    {
-        return new ForkingReporterFactory( trimStackTrace, originalSystemOut );
-    }
-
     public Object createBooterConfiguration( ClassLoader surefireClassLoader, Object factoryInstance,
                                              boolean insideFork )
     {
@@ -324,6 +317,11 @@ public class SurefireReflector
         }
     }
 
+    public void setSystemExitTimeout( Object o, Integer systemExitTimeout )
+    {
+        invokeSetter( o, "setSystemExitTimeout", Integer.class, systemExitTimeout );
+    }
+
     public void setDirectoryScannerParameters( Object o, DirectoryScannerParameters dirScannerParams )
     {
         Object param = createDirectoryScannerParameters( dirScannerParams );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
index e8c5a84..9ef7a94 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
@@ -147,4 +147,6 @@ public interface ProviderParameters
     boolean isInsideFork();
 
     Shutdown getShutdown();
+
+    Integer getSystemExitTimeout();
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java
index d310b9a..c21edf8 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java
@@ -55,4 +55,5 @@ public final class BooterConstants
     public static final String MAIN_CLI_OPTIONS = "mainCliOptions";
     public static final String FAIL_FAST_COUNT = "failFastCount";
     public static final String SHUTDOWN = "shutdown";
+    public static final String SYSTEM_EXIT_TIMEOUT = "systemExitTimeout";
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java
index 02fde8f..208a4be 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java
@@ -102,10 +102,15 @@ public class BooterDeserializer
 
         Shutdown shutdown = Shutdown.valueOf( properties.getProperty( SHUTDOWN ) );
 
+        String systemExitTimeoutAsString = properties.getProperty( SYSTEM_EXIT_TIMEOUT );
+        Integer systemExitTimeout =
+                systemExitTimeoutAsString == null ? null : Integer.valueOf( systemExitTimeoutAsString );
+
         return new ProviderConfiguration( dirScannerParams, runOrderParameters,
                                           properties.getBooleanProperty( FAILIFNOTESTS ), reporterConfiguration, testNg,
                                           testSuiteDefinition, properties.getProperties(), typeEncodedTestForFork,
-                                          preferTestsFromInStream, fromStrings( cli ), failFastCount, shutdown );
+                                          preferTestsFromInStream, fromStrings( cli ), failFastCount, shutdown,
+                                          systemExitTimeout );
     }
 
     public StartupConfiguration getProviderConfiguration()

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
index f95291b..bc8f487 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
@@ -49,7 +49,6 @@ import static org.apache.maven.surefire.booter.Shutdown.KILL;
 import static org.apache.maven.surefire.booter.ForkingRunListener.BOOTERCODE_BYE;
 import static org.apache.maven.surefire.booter.ForkingRunListener.BOOTERCODE_ERROR;
 import static org.apache.maven.surefire.booter.ForkingRunListener.encode;
-import static org.apache.maven.surefire.booter.SurefireReflector.createForkingReporterFactoryInCurrentClassLoader;
 import static org.apache.maven.surefire.booter.SystemPropertyManager.setSystemProperties;
 import static org.apache.maven.surefire.util.ReflectionUtils.instantiateOneArg;
 import static org.apache.maven.surefire.util.internal.DaemonThreadFactory.newDaemonThreadFactory;
@@ -68,11 +67,12 @@ import static java.util.concurrent.TimeUnit.SECONDS;
  */
 public final class ForkedBooter
 {
-    private static final long SYSTEM_EXIT_TIMEOUT_IN_SECONDS = 30;
+    private static final long DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS = 30;
     private static final long PING_TIMEOUT_IN_SECONDS = 20;
-
     private static final ScheduledExecutorService JVM_TERMINATOR = createJvmTerminator();
 
+    private static volatile long systemExitTimeoutInSeconds = DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS;
+
     /**
      * This method is invoked when Surefire is forked - this method parses and organizes the arguments passed to it and
      * then calls the Surefire class' run method. <p/> The system exit code will be 1 if an exception is thrown.
@@ -96,7 +96,8 @@ public final class ForkedBooter
             BooterDeserializer booterDeserializer = new BooterDeserializer( stream );
             ProviderConfiguration providerConfiguration = booterDeserializer.deserialize();
             final StartupConfiguration startupConfiguration = booterDeserializer.getProviderConfiguration();
-
+            systemExitTimeoutInSeconds =
+                    providerConfiguration.systemExitTimeout( DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS );
             TypeEncodedValue forkedTestSet = providerConfiguration.getTestForFork();
             boolean readTestsFromInputStream = providerConfiguration.isReadTestsFromInStream();
 
@@ -255,13 +256,13 @@ public final class ForkedBooter
                                                                  PrintStream originalSystemOut )
     {
         final boolean trimStackTrace = providerConfiguration.getReporterConfiguration().isTrimStackTrace();
-        return createForkingReporterFactoryInCurrentClassLoader( trimStackTrace, originalSystemOut );
+        return new ForkingReporterFactory( trimStackTrace, originalSystemOut );
     }
 
     private static ScheduledExecutorService createJvmTerminator()
     {
         ThreadFactory threadFactory = newDaemonThreadFactory( "last-ditch-daemon-shutdown-thread-"
-                                                            + SYSTEM_EXIT_TIMEOUT_IN_SECONDS
+                                                            + systemExitTimeoutInSeconds
                                                             + "s" );
         ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor( 1, threadFactory );
         executor.setMaximumPoolSize( 1 );
@@ -278,7 +279,7 @@ public final class ForkedBooter
             {
                 Runtime.getRuntime().halt( returnCode );
             }
-        }, SYSTEM_EXIT_TIMEOUT_IN_SECONDS, SECONDS );
+        }, systemExitTimeoutInSeconds, SECONDS );
     }
 
     private static RunResult invokeProviderInSameClassLoader( Object testSet, Object factory,
@@ -325,6 +326,7 @@ public final class ForkedBooter
         bpf.setMainCliOptions( providerConfiguration.getMainCliOptions() );
         bpf.setSkipAfterFailureCount( providerConfiguration.getSkipAfterFailureCount() );
         bpf.setShutdown( providerConfiguration.getShutdown() );
+        bpf.setSystemExitTimeout( providerConfiguration.getSystemExitTimeout() );
         String providerClass = startupConfiguration.getActualClassName();
         return (SurefireProvider) instantiateOneArg( classLoader, providerClass, ProviderParameters.class, bpf );
     }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java
index d6d5237..c2d61e0 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java
@@ -66,9 +66,11 @@ public class ProviderConfiguration
 
     private final List<CommandLineOption> mainCliOptions;
 
-    private int skipAfterFailureCount;
+    private final int skipAfterFailureCount;
 
-    private Shutdown shutdown;
+    private final Shutdown shutdown;
+
+    private final Integer systemExitTimeout;
 
     @SuppressWarnings( "checkstyle:parameternumber" )
     public ProviderConfiguration( DirectoryScannerParameters directoryScannerParameters,
@@ -77,7 +79,7 @@ public class ProviderConfiguration
                                   TestRequest testSuiteDefinition, Map<String, String> providerProperties,
                                   TypeEncodedValue typeEncodedTestSet, boolean readTestsFromInStream,
                                   List<CommandLineOption> mainCliOptions, int skipAfterFailureCount,
-                                  Shutdown shutdown )
+                                  Shutdown shutdown, Integer systemExitTimeout )
     {
         this.runOrderParameters = runOrderParameters;
         this.providerProperties = providerProperties;
@@ -91,6 +93,7 @@ public class ProviderConfiguration
         this.mainCliOptions = mainCliOptions;
         this.skipAfterFailureCount = skipAfterFailureCount;
         this.shutdown = shutdown;
+        this.systemExitTimeout = systemExitTimeout;
     }
 
     public ReporterConfiguration getReporterConfiguration()
@@ -171,4 +174,14 @@ public class ProviderConfiguration
     {
         return shutdown;
     }
+
+    public Integer getSystemExitTimeout()
+    {
+        return systemExitTimeout;
+    }
+
+    public long systemExitTimeout( long fallback )
+    {
+        return systemExitTimeout == null ? fallback : systemExitTimeout;
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/2c6105c5/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
index a29eb14..36f823b 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
@@ -109,6 +109,10 @@ public class ProviderFactory
         surefireReflector.setMainCliOptions( o, providerConfiguration.getMainCliOptions() );
         surefireReflector.setSkipAfterFailureCount( o, providerConfiguration.getSkipAfterFailureCount() );
         surefireReflector.setShutdown( o, providerConfiguration.getShutdown() );
+        if ( isInsideFork )
+        {
+            surefireReflector.setSystemExitTimeout( o, providerConfiguration.getSystemExitTimeout() );
+        }
 
         Object provider = surefireReflector.instantiateProvider( startupConfiguration.getActualClassName(), o );
         currentThread.setContextClassLoader( systemClassLoader );
@@ -116,7 +120,6 @@ public class ProviderFactory
         return new ProviderProxy( provider, classLoader );
     }
 
-
     private final class ProviderProxy
         implements SurefireProvider
     {