[SUREFIRE-1403] [Jigsaw] [Java 9] add "--add-modules ALL-SYSTEM" to forked CLI 
argument


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

Branch: refs/heads/SUREFIRE-1403
Commit: cdc7b64c3dc295c92d4bbc3a150ad0d6de31a764
Parents: 1a65d61
Author: Tibor17 <tibordig...@apache.org>
Authored: Mon Aug 7 12:43:17 2017 +0200
Committer: Tibor17 <tibordig...@apache.org>
Committed: Tue Aug 15 15:54:00 2017 +0200

----------------------------------------------------------------------
 README.md                                       |  18 +-
 maven-failsafe-plugin/pom.xml                   |  43 +--
 .../plugin/failsafe/IntegrationTestMojo.java    |  32 +-
 .../maven/plugin/failsafe/VerifyMojo.java       |   7 +-
 .../failsafe/util/FailsafeSummaryXmlUtils.java  | 112 +++++--
 .../apache/maven/plugin/failsafe/util/JAXB.java | 104 ------
 .../failsafe/MarshallerUnmarshallerTest.java    |  46 ++-
 .../maven/plugin/failsafe/RunResultTest.java    |  17 +-
 .../maven/plugin/failsafe/failsafe-summary.xml  |   2 +-
 maven-surefire-common/pom.xml                   |   2 +-
 .../plugin/surefire/AbstractSurefireMojo.java   |  72 +++-
 .../maven/plugin/surefire/JdkAttributes.java    |  48 +++
 .../booterclient/ForkConfiguration.java         |  72 ++--
 .../surefire/report/StatelessXmlReporter.java   |   4 +-
 ...erDeserializerProviderConfigurationTest.java |   2 +-
 ...terDeserializerStartupConfigurationTest.java |   2 +-
 .../booterclient/ForkConfigurationTest.java     |  65 ++--
 maven-surefire-plugin/pom.xml                   |  27 +-
 .../src/site/markdown/java9.md                  |  92 ++++++
 .../src/site/resources/xsd/failsafe-summary.xjb |  31 --
 maven-surefire-plugin/src/site/site.xml         |   1 +
 pom.xml                                         |  32 +-
 surefire-api/pom.xml                            |   2 +-
 surefire-booter/pom.xml                         |   8 +-
 .../maven/surefire/booter/SystemUtils.java      | 143 +++++++-
 .../maven/surefire/booter/SystemUtilsTest.java  | 330 +++++++++++++++----
 surefire-booter/src/test/resources/jdk/bin/java |   0
 .../src/test/resources/jdk/jre/bin/java         |   0
 .../src/test/resources/jdk8-IBM/release         |   1 +
 .../src/test/resources/jdk8-oracle/release      |   1 +
 .../src/test/resources/jdk9-oracle/release      |   1 +
 surefire-integration-tests/pom.xml              |   4 +-
 .../maven/surefire/its/AbstractJigsawIT.java    | 113 +++++++
 .../maven/surefire/its/Java9FullApiIT.java      |  95 ++++++
 .../surefire/its/jiras/Surefire1265Java9IT.java |  17 +-
 .../src/test/resources/java9-full-api/pom.xml   | 122 +++++++
 .../java9-full-api/src/test/java/J9IT.java      |  39 +++
 .../java9-full-api/src/test/java/J9Test.java    |  39 +++
 surefire-setup-integration-tests/pom.xml        |  28 +-
 .../src/main/resources/toolchains.xml           |  35 ++
 40 files changed, 1360 insertions(+), 449 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index e7b4b07..20fef40 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
 
 [JIRA Change Log]
 
-[![tag](http://img.shields.io/github/tag/apache/maven-surefire.svg)](https://github.com/apache/maven-surefire/releases)
+[![tag](http://img.shields.io/github/tag/apache/maven-surefire.svg)](https://github.com/apache/maven-surefire/releases/tag/surefire-2.20)
 
 Usage of [maven-surefire-plugin], [maven-failsafe-plugin], 
[maven-surefire-report-plugin].
 
@@ -20,16 +20,20 @@ Usage of [maven-surefire-plugin], [maven-failsafe-plugin], 
[maven-surefire-repor
 
 
[![dependencies](https://www.versioneye.com/java/org.apache.maven.plugins:maven-surefire-plugin/badge.svg?style=plastic)](https://builds.apache.org/job/maven-surefire/depgraph-view/)
 Maven 2.2.1 Plugin API
 
-[![license](http://img.shields.io/:license-apache-red.svg?style=plastic)](http://www.apache.org/licenses/LICENSE-2.0.html)
 
[![coverage](https://img.shields.io/jenkins/c/https/builds.apache.org/maven-surefire.svg?style=plastic)](https://builds.apache.org/job/maven-surefire/jacoco/)
 
[![tests](https://img.shields.io/jenkins/t/https/builds.apache.org/maven-surefire.svg?style=plastic)](https://builds.apache.org/job/maven-surefire/lastBuild/testReport/)
 [![Build 
Status](https://builds.apache.org/job/maven-surefire/badge/icon?style=plastic)](https://builds.apache.org/job/maven-surefire)
 [![Build 
Status](https://builds.apache.org/job/maven-surefire-windows/badge/icon?style=plastic)](https://builds.apache.org/job/maven-surefire-windows)
 [![Build 
Status](https://builds.apache.org/job/maven-surefire-mvn-2.2.1/badge/icon?style=plastic)](https://builds.apache.org/job/maven-surefire-mvn-2.2.1)
+[![license](http://img.shields.io/:license-apache-red.svg?style=plastic)](http://www.apache.org/licenses/LICENSE-2.0.html)
 
[![coverage](https://img.shields.io/jenkins/c/https/builds.apache.org/maven-surefire.svg?style=plastic)](https://builds.apache.org/job/maven-surefire/jacoco/)
 
[![tests](https://img.shields.io/jenkins/t/https/builds.apache.org/maven-surefire.svg?style=plastic)](https://builds.apache.org/job/maven-surefire/lastBuild/testReport/)
 [![Build 
Status](https://builds.apache.org/job/maven-surefire/badge/icon?style=plastic)](https://builds.apache.org/job/maven-surefire)
 [![Build 
Status](https://builds.apache.org/job/maven-surefire-windows/badge/icon?style=plastic)](https://builds.apache.org/job/maven-surefire-windows)
 
 # Development Information
 
-Surefire needs to use Maven 3.1.0+ and JDK 1.6+ to be built.
-But in order to run IT tests, you can do:
-* In order to run tests for a release check during the vote the following 
memory requirements are needed:
-  $ export MAVEN_OPTS="-Xmx768m -XX:MaxPermSize=1g 
-XX:SoftRefLRUPolicyMSPerMB=50 -Djava.awt.headless=true"
-* $ mvn install site site:stage -P reporting,run-its
+In order to build Surefire project use **Maven 3.1.0+** and **JDK 1.8**.   
 
+But in order to run IT tests, you can do:   
+
+* In order to run tests for a release check during the vote the following 
memory requirements are needed:   
+  **(on Linux/Unix)** *export MAVEN_OPTS="-Xmx768m -XX:MaxMetaspaceSize=864m 
-XX:SoftRefLRUPolicyMSPerMB=50 -Djava.awt.headless=true"*  
+  **(on Windows)** *set MAVEN_OPTS="-Xmx768m -XX:MaxMetaspaceSize=864m 
-XX:SoftRefLRUPolicyMSPerMB=50 -Djava.awt.headless=true"*    
+* In order to run the build with **JDK 9** **on Windows** (**on Linux/Unix 
modify system property jdk.home**):  
+  *mvn install site site:stage -P reporting,run-its "-Djdk.home=e:\Program 
Files\Java\jdk9\"* 
+  
 Deploying web site
 ------------------
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-failsafe-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/maven-failsafe-plugin/pom.xml b/maven-failsafe-plugin/pom.xml
index ec48929..4233139 100644
--- a/maven-failsafe-plugin/pom.xml
+++ b/maven-failsafe-plugin/pom.xml
@@ -66,39 +66,6 @@
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.cxf</groupId>
-        <artifactId>cxf-xjc-plugin</artifactId>
-        <version>3.1.0</version>
-        <executions>
-          <execution>
-            <id>generate-failsafe-summary</id>
-            <goals>
-              <goal>xsdtojava</goal>
-            </goals>
-            <configuration>
-              
<sourceRoot>${project.build.directory}/generated-sources/jaxb</sourceRoot>
-              <xsdOptions>
-                <xsdOption>
-                  <!--
-                  Due to historical reasons and due to both Surefire and 
Failsafe Plugin have very similar project
-                  pages (mvn site), the Maven Site for both projects is 
generated upon one common location in
-                  maven-surefire-plugin. The XSD files are located in 
maven-surefire-plugin project. Do NOT duplicate
-                  the XSD in to maven-failsafe-plugin.
-                  -->
-                  
<xsd>../maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xsd</xsd>
-                  
<bindingFile>../maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xjb</bindingFile>
-                  
<packagename>org.apache.maven.plugin.failsafe.xmlsummary</packagename>
-                  <extensionArgs>
-                    <arg>-encoding</arg>
-                    <arg>${project.build.sourceEncoding}</arg>
-                  </extensionArgs>
-                </xsdOption>
-              </xsdOptions>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-plugin-plugin</artifactId>
         <configuration>
@@ -211,6 +178,8 @@
               <artifactSet>
                 <includes>
                   <include>org.apache.maven.shared:maven-shared-utils</include>
+                  <include>commons-io:commons-io</include>
+                  <include>org.apache.commons:commons-lang3</include>
                 </includes>
               </artifactSet>
               <relocations>
@@ -218,6 +187,14 @@
                   <pattern>org.apache.maven.shared</pattern>
                   
<shadedPattern>org.apache.maven.surefire.shade.org.apache.maven.shared</shadedPattern>
                 </relocation>
+                <relocation>
+                  <pattern>org.apache.commons.io</pattern>
+                  
<shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.io</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>org.apache.commons.lang3</pattern>
+                  
<shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.lang3</shadedPattern>
+                </relocation>
               </relocations>
             </configuration>
           </execution>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/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 28b2859..723a4a1 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
@@ -27,10 +27,8 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
 import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.shared.utils.StringUtils;
 import org.apache.maven.surefire.suite.RunResult;
 
-import javax.xml.bind.JAXBException;
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
@@ -40,7 +38,6 @@ import java.util.List;
 import java.util.Locale;
 
 import static 
org.apache.maven.plugin.failsafe.util.FailsafeSummaryXmlUtils.writeSummary;
-import static org.apache.maven.shared.utils.ReaderFactory.FILE_ENCODING;
 
 /**
  * Run integration tests using Surefire.
@@ -258,6 +255,9 @@ public class IntegrationTestMojo
 
     /**
      * The character encoding scheme to be applied.
+     * Deprecated since 2.20.1 and used encoding UTF-8 in 
<tt>failsafe-summary.xml</tt>.
+     *
+     * @deprecated since of 2.20.1
      */
     @Parameter( property = "encoding", defaultValue = 
"${project.reporting.outputEncoding}" )
     private String encoding;
@@ -390,13 +390,9 @@ public class IntegrationTestMojo
         try
         {
             Object token = getPluginContext().get( 
FAILSAFE_IN_PROGRESS_CONTEXT_KEY );
-            writeSummary( summary, summaryFile, token != null, toCharset( 
getEncodingOrDefault() ) );
-        }
-        catch ( IOException e )
-        {
-            throw new MojoExecutionException( e.getMessage(), e );
+            writeSummary( summary, summaryFile, token != null );
         }
-        catch ( JAXBException e )
+        catch ( Exception e )
         {
             throw new MojoExecutionException( e.getMessage(), e );
         }
@@ -404,24 +400,6 @@ public class IntegrationTestMojo
         getPluginContext().put( FAILSAFE_IN_PROGRESS_CONTEXT_KEY, 
FAILSAFE_IN_PROGRESS_CONTEXT_KEY );
     }
 
-    private String getEncodingOrDefault()
-    {
-        if ( StringUtils.isEmpty( encoding ) )
-        {
-            getConsoleLogger()
-                    .warning( "File encoding has not been set, using platform 
encoding "
-                                      + FILE_ENCODING
-                                      + ", i.e. build is platform dependent! 
The file encoding for reports output files"
-                                      + " should be provided by the POM 
property ${project.reporting.outputEncoding}."
-            );
-            return FILE_ENCODING;
-        }
-        else
-        {
-            return encoding;
-        }
-    }
-
     private boolean isJarArtifact( File artifactFile )
     {
         return artifactFile != null && artifactFile.isFile() && 
artifactFile.getName().toLowerCase().endsWith( ".jar" );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java
----------------------------------------------------------------------
diff --git 
a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java
 
b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java
index 04cc72c..3075a6f 100644
--- 
a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java
+++ 
b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java
@@ -34,7 +34,6 @@ import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.surefire.cli.CommandLineOption;
 import org.apache.maven.surefire.suite.RunResult;
 
-import javax.xml.bind.JAXBException;
 import java.io.File;
 import java.util.Collection;
 
@@ -145,7 +144,9 @@ public class VerifyMojo
 
     /**
      * The character encoding scheme to be applied.
+     * Deprecated since 2.20.1 and used encoding UTF-8 in 
<tt>failsafe-summary.xml</tt>.
      *
+     * @deprecated since of 2.20.1
      * @noinspection UnusedDeclaration
      */
     @Parameter( property = "encoding", defaultValue = 
"${project.reporting.outputEncoding}" )
@@ -184,7 +185,7 @@ public class VerifyMojo
                     }
                 }
             }
-            catch ( JAXBException e )
+            catch ( Exception e )
             {
                 throw new MojoExecutionException( e.getMessage(), e );
             }
@@ -208,7 +209,7 @@ public class VerifyMojo
         return consoleLogger;
     }
 
-    private RunResult readSummary( File summaryFile ) throws JAXBException
+    private RunResult readSummary( File summaryFile ) throws Exception
     {
         return FailsafeSummaryXmlUtils.toRunResult( summaryFile );
     }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java
----------------------------------------------------------------------
diff --git 
a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java
 
b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java
index 1f3f64d..d06da13 100644
--- 
a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java
+++ 
b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/FailsafeSummaryXmlUtils.java
@@ -19,16 +19,26 @@ package org.apache.maven.plugin.failsafe.util;
  * under the License.
  */
 
-import org.apache.maven.plugin.failsafe.xmlsummary.ErrorType;
-import org.apache.maven.plugin.failsafe.xmlsummary.FailsafeSummary;
+import org.apache.commons.io.IOUtils;
 import org.apache.maven.surefire.suite.RunResult;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
 
-import javax.xml.bind.JAXBException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
-import java.nio.charset.Charset;
+import java.util.Locale;
 
+import static java.lang.Boolean.parseBoolean;
+import static java.lang.Integer.parseInt;
+import static org.apache.commons.lang3.StringEscapeUtils.escapeXml10;
+import static org.apache.commons.lang3.StringEscapeUtils.unescapeXml;
 import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
+import static org.apache.maven.surefire.util.internal.StringUtils.isBlank;
 
 /**
  * @author <a href="mailto:tibordig...@apache.org";>Tibor Digana (tibor17)</a>
@@ -36,46 +46,86 @@ import static 
org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
  */
 public final class FailsafeSummaryXmlUtils
 {
+    private static final String FAILSAFE_SUMMARY_XML_SCHEMA_LOCATION =
+            
"https://maven.apache.org/surefire/maven-surefire-plugin/xsd/failsafe-summary.xsd";;
+
+    private static final String FAILSAFE_SUMMARY_XML_NIL_ATTR =
+            " xsi:nil=\"true\" 
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";;
+
+    private static final String FAILSAFE_SUMMARY_XML_TEMPLATE =
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+                    + "<failsafe-summary 
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
+                    + " xsi:noNamespaceSchemaLocation=\"" + 
FAILSAFE_SUMMARY_XML_SCHEMA_LOCATION + "\""
+                    + " result=\"%s\" timeout=\"%s\">\n"
+                    + "    <completed>%d</completed>\n"
+                    + "    <errors>%d</errors>\n"
+                    + "    <failures>%d</failures>\n"
+                    + "    <skipped>%d</skipped>\n"
+                    + "    <failureMessage%s>%s</failureMessage>\n"
+                    + "</failsafe-summary>";
+
     private FailsafeSummaryXmlUtils()
     {
         throw new IllegalStateException( "No instantiable constructor." );
     }
 
-    public static RunResult toRunResult( File failsafeSummaryXml ) throws 
JAXBException
+    public static RunResult toRunResult( File failsafeSummaryXml ) throws 
Exception
     {
-        FailsafeSummary failsafeSummary = JAXB.unmarshal( failsafeSummaryXml, 
FailsafeSummary.class );
+        XPathFactory xpathFactory = XPathFactory.newInstance();
+        XPath xpath = xpathFactory.newXPath();
 
-        return new RunResult( failsafeSummary.getCompleted(), 
failsafeSummary.getErrors(),
-                                    failsafeSummary.getFailures(), 
failsafeSummary.getSkipped(),
-                                    failsafeSummary.getFailureMessage(), 
failsafeSummary.isTimeout()
-        );
+        FileInputStream is = new FileInputStream( failsafeSummaryXml );
+
+        try
+        {
+            Node root = (Node) xpath.evaluate( "/", new InputSource( is ), 
XPathConstants.NODE );
+
+            String completed = xpath.evaluate( "/failsafe-summary/completed", 
root );
+            String errors = xpath.evaluate( "/failsafe-summary/errors", root );
+            String failures = xpath.evaluate( "/failsafe-summary/failures", 
root );
+            String skipped = xpath.evaluate( "/failsafe-summary/skipped", root 
);
+            String failureMessage = xpath.evaluate( 
"/failsafe-summary/failureMessage", root );
+            String timeout = xpath.evaluate( "/failsafe-summary/@timeout", 
root );
+
+            return new RunResult( parseInt( completed ), parseInt( errors ), 
parseInt( failures ), parseInt( skipped ),
+                                        isBlank( failureMessage ) ? null : 
unescapeXml( failureMessage ),
+                                        parseBoolean( timeout )
+            );
+        }
+        finally
+        {
+            is.close();
+        }
     }
 
     public static void fromRunResultToFile( RunResult fromRunResult, File 
toFailsafeSummaryXml )
-            throws JAXBException, IOException
+            throws IOException
     {
-        fromRunResultToFile( fromRunResult, toFailsafeSummaryXml, UTF_8 );
-    }
+        String failure = fromRunResult.getFailure();
+        String xml = String.format( Locale.ROOT, FAILSAFE_SUMMARY_XML_TEMPLATE,
+                                          fromRunResult.getFailsafeCode(),
+                                          String.valueOf( 
fromRunResult.isTimeout() ),
+                                          fromRunResult.getCompletedCount(),
+                                          fromRunResult.getErrors(),
+                                          fromRunResult.getFailures(),
+                                          fromRunResult.getSkipped(),
+                                          isBlank( failure ) ? 
FAILSAFE_SUMMARY_XML_NIL_ATTR : "",
+                                          isBlank( failure ) ? "" : 
escapeXml10( failure )
+        );
 
-    public static void fromRunResultToFile( RunResult fromRunResult, File 
toFailsafeSummaryXml, Charset encoding )
-            throws JAXBException, IOException
-    {
-        FailsafeSummary summary = new FailsafeSummary();
-        summary.setCompleted( fromRunResult.getCompletedCount() );
-        summary.setFailureMessage( fromRunResult.getFailure() );
-        summary.setErrors( fromRunResult.getErrors() );
-        summary.setFailures( fromRunResult.getFailures() );
-        summary.setSkipped( fromRunResult.getSkipped() );
-        summary.setTimeout( fromRunResult.isTimeout() );
-        Integer errorCode = fromRunResult.getFailsafeCode();
-        summary.setResult( errorCode == null ? null : ErrorType.fromValue( 
String.valueOf( errorCode ) ) );
-
-        JAXB.marshal( summary, encoding, toFailsafeSummaryXml );
+        FileOutputStream os = new FileOutputStream( toFailsafeSummaryXml );
+        try
+        {
+            IOUtils.write( xml, os, UTF_8 );
+        }
+        finally
+        {
+            os.close();
+        }
     }
 
-    public static void writeSummary( RunResult mergedSummary, File 
mergedSummaryFile, boolean inProgress,
-                                     Charset encoding )
-            throws IOException, JAXBException
+    public static void writeSummary( RunResult mergedSummary, File 
mergedSummaryFile, boolean inProgress )
+            throws Exception
     {
         if ( !mergedSummaryFile.getParentFile().isDirectory() )
         {
@@ -89,6 +139,6 @@ public final class FailsafeSummaryXmlUtils
             mergedSummary = mergedSummary.aggregate( runResult );
         }
 
-        fromRunResultToFile( mergedSummary, mergedSummaryFile, encoding );
+        fromRunResultToFile( mergedSummary, mergedSummaryFile );
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/JAXB.java
----------------------------------------------------------------------
diff --git 
a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/JAXB.java
 
b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/JAXB.java
deleted file mode 100644
index ac51292..0000000
--- 
a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/util/JAXB.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package org.apache.maven.plugin.failsafe.util;
-
-/*
- * 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 javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.PropertyException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.helpers.DefaultValidationEventHandler;
-import javax.xml.namespace.QName;
-import javax.xml.transform.stream.StreamSource;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import static javax.xml.bind.JAXBContext.newInstance;
-import static javax.xml.bind.Marshaller.JAXB_ENCODING;
-import static javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT;
-import static javax.xml.bind.Marshaller.JAXB_FRAGMENT;
-
-/**
- * @author <a href="mailto:tibordig...@apache.org";>Tibor Digana (tibor17)</a>
- * @since 2.20
- */
-public final class JAXB
-{
-    private JAXB()
-    {
-        throw new IllegalStateException( "Not instantiated constructor." );
-    }
-
-    public static <T> T unmarshal( File source, Class<T> rootXmlNode ) throws 
JAXBException
-    {
-        return unmarshal( source, rootXmlNode, Collections.<String, 
Object>emptyMap() );
-    }
-
-    public static <T> T unmarshal( File source, Class<T> rootXmlNode, 
Map<String, ?> props )
-            throws JAXBException
-    {
-        Class<?>[] classesToBeBound = { rootXmlNode };
-        JAXBContext ctx = newInstance( classesToBeBound );
-        Unmarshaller unmarshaller = ctx.createUnmarshaller();
-        properties( props, unmarshaller );
-        unmarshaller.setEventHandler( new DefaultValidationEventHandler() );
-        JAXBElement<T> element = unmarshaller.unmarshal( new StreamSource( 
source ), rootXmlNode );
-        return element.getValue();
-    }
-
-    @SuppressWarnings( "unchecked" )
-    public static <T> void marshal( T bean, Charset encoding, File destination 
) throws JAXBException, IOException
-    {
-        Class<T> type = (Class<T>) bean.getClass();
-        JAXBElement<T> rootElement = buildJaxbElement( bean, type );
-        Class<?>[] classesToBeBound = { type };
-        JAXBContext context = newInstance( classesToBeBound );
-        Marshaller marshaller = context.createMarshaller();
-        marshaller.setProperty( JAXB_ENCODING, encoding.name() );
-        marshaller.setProperty( JAXB_FORMATTED_OUTPUT, true );
-        marshaller.setProperty( JAXB_FRAGMENT, true );
-        marshaller.marshal( rootElement, destination );
-    }
-
-    private static <T> JAXBElement<T> buildJaxbElement( T bean, Class<T> type )
-    {
-        XmlRootElement xmlRootElement = type.getAnnotation( 
XmlRootElement.class );
-        if ( xmlRootElement == null )
-        {
-            return null;
-        }
-        QName root = new QName( "", xmlRootElement.name() );
-        return new JAXBElement<T>( root, type, bean );
-    }
-
-    private static void properties( Map<String, ?> props, Unmarshaller 
unmarshaller ) throws PropertyException
-    {
-        for ( Entry<String, ?> e : props.entrySet() )
-        {
-            unmarshaller.setProperty( e.getKey(), e.getValue() );
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/MarshallerUnmarshallerTest.java
----------------------------------------------------------------------
diff --git 
a/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/MarshallerUnmarshallerTest.java
 
b/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/MarshallerUnmarshallerTest.java
index 8d5d32f..96708a8 100644
--- 
a/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/MarshallerUnmarshallerTest.java
+++ 
b/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/MarshallerUnmarshallerTest.java
@@ -19,14 +19,12 @@ package org.apache.maven.plugin.failsafe;
  * under the License.
  */
 
-import org.apache.maven.plugin.failsafe.util.JAXB;
-import org.apache.maven.plugin.failsafe.xmlsummary.FailsafeSummary;
+import org.apache.maven.plugin.failsafe.util.FailsafeSummaryXmlUtils;
+import org.apache.maven.surefire.suite.RunResult;
 import org.junit.Test;
 
 import java.io.File;
 
-import static org.apache.maven.plugin.failsafe.xmlsummary.ErrorType.FAILURE;
-import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
 import static org.fest.assertions.Assertions.assertThat;
 
 public class MarshallerUnmarshallerTest
@@ -35,9 +33,9 @@ public class MarshallerUnmarshallerTest
     public void shouldUnmarshallExistingXmlFile() throws Exception
     {
         File xml = new File( 
"target/test-classes/org/apache/maven/plugin/failsafe/failsafe-summary.xml" );
-        FailsafeSummary summary = JAXB.unmarshal( xml, FailsafeSummary.class );
+        RunResult summary = FailsafeSummaryXmlUtils.toRunResult( xml );
 
-        assertThat( summary.getCompleted() )
+        assertThat( summary.getCompletedCount() )
                 .isEqualTo( 7 );
 
         assertThat( summary.getErrors() )
@@ -49,14 +47,14 @@ public class MarshallerUnmarshallerTest
         assertThat( summary.getSkipped() )
                 .isEqualTo( 3 );
 
-        assertThat( summary.getFailureMessage() )
+        assertThat( summary.getFailure() )
                 .contains( "There was an error in the forked processtest "
                                    + "subsystem#no method RuntimeException Hi 
There!"
                 );
 
-        assertThat( summary.getFailureMessage() )
+        assertThat( summary.getFailure() )
                 .contains( "There was an error in the forked processtest "
-                                   + "subsystem#no method RuntimeException Hi 
There!"
+                                   + "subsystem#no method RuntimeException Hi 
There! $&>>"
                                    + "\n\tat 
org.apache.maven.plugin.surefire.booterclient.ForkStarter"
                                    + ".awaitResultsDone(ForkStarter.java:489)"
                 );
@@ -65,23 +63,17 @@ public class MarshallerUnmarshallerTest
     @Test
     public void shouldMarshallAndUnmarshallSameXml() throws Exception
     {
-        FailsafeSummary expected = new FailsafeSummary();
-        expected.setResult( FAILURE );
-        expected.setTimeout( true );
-        expected.setCompleted( 7 );
-        expected.setErrors( 1 );
-        expected.setFailures( 2 );
-        expected.setSkipped( 3 );
-        expected.setFailureMessage( "There was an error in the forked 
processtest "
-                                            + "subsystem#no method 
RuntimeException Hi There!"
-                                            + "\n\tat 
org.apache.maven.plugin.surefire.booterclient.ForkStarter"
-                                            + 
".awaitResultsDone(ForkStarter.java:489)"
-        );
+        RunResult expected =
+                new RunResult( 7, 1, 2, 3, 2,
+                                     "There was an error in the forked 
processtest "
+                                             + "subsystem#no method 
RuntimeException Hi There! $&>>"
+                                             + "\n\tat 
org.apache.maven.plugin.surefire.booterclient.ForkStarter"
+                                             + 
".awaitResultsDone(ForkStarter.java:489)", true );
 
         File xml = File.createTempFile( "failsafe-summary", ".xml" );
-        JAXB.marshal( expected, UTF_8, xml );
+        FailsafeSummaryXmlUtils.writeSummary( expected, xml, false );
 
-        FailsafeSummary actual = JAXB.unmarshal( xml, FailsafeSummary.class );
+        RunResult actual = FailsafeSummaryXmlUtils.toRunResult( xml );
 
         assertThat( actual.getFailures() )
                 .isEqualTo( expected.getFailures() );
@@ -89,8 +81,8 @@ public class MarshallerUnmarshallerTest
         assertThat( actual.isTimeout() )
                 .isEqualTo( expected.isTimeout() );
 
-        assertThat( actual.getCompleted() )
-                .isEqualTo( expected.getCompleted() );
+        assertThat( actual.getCompletedCount() )
+                .isEqualTo( expected.getCompletedCount() );
 
         assertThat( actual.getErrors() )
                 .isEqualTo( expected.getErrors() );
@@ -101,7 +93,7 @@ public class MarshallerUnmarshallerTest
         assertThat( actual.getSkipped() )
                 .isEqualTo( expected.getSkipped() );
 
-        assertThat( actual.getFailureMessage() )
-                .isEqualTo( expected.getFailureMessage() );
+        assertThat( actual.getFailure() )
+                .isEqualTo( expected.getFailure() );
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java
----------------------------------------------------------------------
diff --git 
a/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java
 
b/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java
index f7b62b6..5e75ebf 100644
--- 
a/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java
+++ 
b/maven-failsafe-plugin/src/test/java/org/apache/maven/plugin/failsafe/RunResultTest.java
@@ -23,12 +23,9 @@ import 
org.apache.maven.plugin.failsafe.util.FailsafeSummaryXmlUtils;
 import org.apache.maven.surefire.suite.RunResult;
 import org.junit.Test;
 
-import javax.xml.bind.JAXBException;
 import java.io.File;
-import java.io.IOException;
 import java.nio.charset.Charset;
 
-import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
 import static org.fest.assertions.Assertions.assertThat;
 
 /**
@@ -61,35 +58,35 @@ public class RunResultTest
 
     @Test
     public void testSerialization()
-            throws IOException, JAXBException
+            throws Exception
     {
         writeReadCheck( getSimpleAggregate() );
     }
 
     @Test
     public void testFailures()
-            throws IOException, JAXBException
+            throws Exception
     {
         writeReadCheck( new RunResult( 0, 1, 2, 3, "stacktraceHere", false ) );
     }
 
     @Test
     public void testSkipped()
-            throws IOException, JAXBException
+            throws Exception
     {
         writeReadCheck( new RunResult( 3, 2, 1, 0, null, true ) );
     }
 
     @Test
     public void testAppendSerialization()
-            throws IOException, JAXBException
+            throws Exception
     {
         RunResult simpleAggregate = getSimpleAggregate();
         RunResult additional = new RunResult( 2, 1, 2, 2, "msg " + ( (char) 
0x0E01 ), true );
 
         File summary = File.createTempFile( "failsafe", "test" );
-        FailsafeSummaryXmlUtils.writeSummary( simpleAggregate, summary, false, 
UTF_8 );
-        FailsafeSummaryXmlUtils.writeSummary( additional, summary, true, UTF_8 
);
+        FailsafeSummaryXmlUtils.writeSummary( simpleAggregate, summary, false 
);
+        FailsafeSummaryXmlUtils.writeSummary( additional, summary, true );
         RunResult actual = FailsafeSummaryXmlUtils.toRunResult( summary );
         //noinspection ResultOfMethodCallIgnored
         summary.delete();
@@ -132,7 +129,7 @@ public class RunResultTest
     }
 
     private void writeReadCheck( RunResult expected )
-            throws IOException, JAXBException
+            throws Exception
     {
         File tmp = File.createTempFile( "test", "xml" );
         FailsafeSummaryXmlUtils.fromRunResultToFile( expected, tmp );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-failsafe-plugin/src/test/resources/org/apache/maven/plugin/failsafe/failsafe-summary.xml
----------------------------------------------------------------------
diff --git 
a/maven-failsafe-plugin/src/test/resources/org/apache/maven/plugin/failsafe/failsafe-summary.xml
 
b/maven-failsafe-plugin/src/test/resources/org/apache/maven/plugin/failsafe/failsafe-summary.xml
index b1fe1f9..2b15bca 100644
--- 
a/maven-failsafe-plugin/src/test/resources/org/apache/maven/plugin/failsafe/failsafe-summary.xml
+++ 
b/maven-failsafe-plugin/src/test/resources/org/apache/maven/plugin/failsafe/failsafe-summary.xml
@@ -1 +1 @@
-<?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.
-->
<failsafe-summary result="254" timeout="false">
  <completed>7</completed>
  <errors>1</errors>
  <failures>2</failures>
  <skipped>3</skipped>
  <failureMessage>
 <![CDATA[org.apache.maven.surefire.booter.SurefireBooterForkException: 
ExecutionException There was an error in the forked processtest subsystem#no 
method RuntimeException Hi There!
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.awaitResultsDone(ForkStarter.java:489)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.runSuitesForkOnceMultiple(ForkStarter.java:364)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:288)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:240)
        at 
org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1075)
        at 
org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:905)
        at 
org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:783)
        at 
org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:133)
        
 at 
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        at 
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at 
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at 
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:108)
        at 
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:76)
        at 
org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at 
org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:116)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:361)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:155)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:584)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:213)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:157)
        at 
 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at 
org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at 
org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at 
org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at 
org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: java.lang.RuntimeException: There was an error in the forked 
processtest subsystem#no method RuntimeException Hi There!
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:658)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:527)
        at org.apache.maven.plugin.surefire.booterclient.ForkStarter.acces
 s$500(ForkStarter.java:117)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter$1.call(ForkStarter.java:358)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter$1.call(ForkStarter.java:337)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
]]></failureMessage>
</failsafe-summary>
\ No newline at end of file
+<?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.
-->
<failsafe-summary result="254" timeout="false">
  <completed>7</completed>
  <errors>1</errors>
  <failures>2</failures>
  <skipped>3</skipped>
  <failureMessage>
 <![CDATA[org.apache.maven.surefire.booter.SurefireBooterForkException: 
ExecutionException There was an error in the forked processtest subsystem#no 
method RuntimeException Hi There! $&amp;&gt;&gt;
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.awaitResultsDone(ForkStarter.java:489)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.runSuitesForkOnceMultiple(ForkStarter.java:364)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:288)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:240)
        at 
org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1075)
        at 
org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:905)
        at 
org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:783)
        at 
org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginMana
 ger.java:133)
        at 
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        at 
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at 
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at 
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:108)
        at 
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:76)
        at 
org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at 
org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:116)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:361)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:155)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:584)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:213)
        at org.apache.maven.cli.MavenCli.main(MavenCli
 .java:157)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at 
org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at 
org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at 
org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at 
org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: java.lang.RuntimeException: There was an error in the forked 
processtest subsystem#no method RuntimeException Hi There!
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:658)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:527)
        at org.apache.maven.plugin.surefire.booterclient.Fo
 rkStarter.access$500(ForkStarter.java:117)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter$1.call(ForkStarter.java:358)
        at 
org.apache.maven.plugin.surefire.booterclient.ForkStarter$1.call(ForkStarter.java:337)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
]]></failureMessage>
</failsafe-summary>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-surefire-common/pom.xml
----------------------------------------------------------------------
diff --git a/maven-surefire-common/pom.xml b/maven-surefire-common/pom.xml
index ae050c7..121609b 100644
--- a/maven-surefire-common/pom.xml
+++ b/maven-surefire-common/pom.xml
@@ -160,7 +160,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <jvm>${test.jre}/bin/java</jvm>
+          <jvm>${jdk.home}/bin/java</jvm>
           <redirectTestOutputToFile>true</redirectTestOutputToFile>
           <includes>
             <include>**/JUnit4SuiteTest.java</include>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/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 f2e5bfb..047f7a4 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
@@ -77,6 +77,7 @@ import 
org.apache.maven.surefire.testset.TestSetFailedException;
 import org.apache.maven.surefire.util.DefaultScanResult;
 import org.apache.maven.surefire.util.RunOrder;
 import org.apache.maven.surefire.util.SurefireReflectionException;
+import org.apache.maven.toolchain.DefaultToolchain;
 import org.apache.maven.toolchain.Toolchain;
 import org.apache.maven.toolchain.ToolchainManager;
 
@@ -100,13 +101,21 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import static java.lang.Thread.currentThread;
+import static java.util.Collections.singletonMap;
 import static org.apache.commons.lang3.JavaVersion.JAVA_1_7;
+import static org.apache.commons.lang3.JavaVersion.JAVA_9;
+import static org.apache.commons.lang3.JavaVersion.JAVA_RECENT;
 import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
 import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast;
 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;
+import static org.apache.maven.shared.utils.StringUtils.isNotEmpty;
 import static org.apache.maven.shared.utils.StringUtils.split;
+import static org.apache.maven.surefire.booter.SystemUtils.endsWithJavaPath;
+import static org.apache.maven.surefire.booter.SystemUtils.isJava9AtLeast;
+import static 
org.apache.maven.surefire.booter.SystemUtils.toJdkHomeFromJvmExec;
+import static 
org.apache.maven.surefire.booter.SystemUtils.toJdkVersionFromReleaseFile;
 import static org.apache.maven.surefire.suite.RunResult.failure;
 import static org.apache.maven.surefire.suite.RunResult.noTestsRun;
 import static org.apache.maven.surefire.util.ReflectionUtils.invokeGetter;
@@ -123,6 +132,10 @@ public abstract class AbstractSurefireMojo
     extends AbstractMojo
     implements SurefireExecutionParameters
 {
+    private static final Map<String, String> JAVA_9_MATCHER_OLD_NOTATION = 
singletonMap( "version", "[1.9,)" );
+
+    private static final Map<String, String> JAVA_9_MATCHER = singletonMap( 
"version", "[9,)" );
+
     private static final Platform PLATFORM = new Platform();
 
     private static final File SYSTEM_TMP_DIR = new File( System.getProperty( 
"java.io.tmpdir" ) );
@@ -895,7 +908,7 @@ public abstract class AbstractSurefireMojo
             getConsoleLogger().info( "Toolchain in maven-" + getPluginName() + 
"-plugin: " + toolchain );
             if ( jvmToUse != null )
             {
-                getConsoleLogger().warning( "Toolchains are ignored, 
'executable' parameter is set to " + jvmToUse );
+                getConsoleLogger().warning( "Toolchains are ignored, 'jvm' 
parameter is set to " + jvmToUse );
             }
         }
 
@@ -1947,7 +1960,7 @@ public abstract class AbstractSurefireMojo
                                                     
startupReportConfiguration, consoleLogger );
     }
 
-    protected ForkConfiguration getForkConfiguration()
+    private ForkConfiguration getForkConfiguration() throws 
MojoFailureException
     {
         File tmpDir = getSurefireTempDir();
 
@@ -2038,24 +2051,59 @@ public abstract class AbstractSurefireMojo
         return debugForkedProcess;
     }
 
-    private String getEffectiveJvm()
+    private JdkAttributes getEffectiveJvm() throws MojoFailureException
     {
-        String jvmToUse = getJvm();
-        if ( toolchain != null && jvmToUse == null )
+        if ( isNotEmpty( jvm ) )
         {
-            jvmToUse = toolchain.findTool( "java" ); //NOI18N
+            File pathToJava = new File( jvm ).getAbsoluteFile();
+            if ( !endsWithJavaPath( pathToJava.getPath() ) )
+            {
+                throw new MojoFailureException( "Given path does not end with 
java executor \""
+                                                        + pathToJava.getPath() 
+ "\"." );
+            }
+
+            if ( !( pathToJava.isFile()
+                            || "java".equals( pathToJava.getName() ) && 
pathToJava.getParentFile().isDirectory() ) )
+            {
+                throw new MojoFailureException( "Given path to java executor 
does not exist \""
+                                                        + pathToJava.getPath() 
+ "\"." );
+            }
+
+            File jdkHome = toJdkHomeFromJvmExec( pathToJava.getPath() );
+            Double version = jdkHome == null ? null : 
toJdkVersionFromReleaseFile( jdkHome );
+            boolean javaVersion9 = version == null ? isJava9AtLeast( 
pathToJava.getPath() ) : isJava9AtLeast( version );
+            return new JdkAttributes( pathToJava.getPath(), javaVersion9 );
         }
 
-        if ( isEmpty( jvmToUse ) )
+        if ( toolchain != null )
         {
-            // use the same JVM as the one used to run Maven (the "java.home" 
one)
-            jvmToUse = System.getProperty( "java.home" ) + File.separator + 
"bin" + File.separator + "java";
-            getConsoleLogger().debug( "Using JVM: " + jvmToUse );
+            String jvmToUse = toolchain.findTool( "java" );
+            if ( isNotEmpty( jvmToUse ) )
+            {
+                boolean javaVersion9 = false;
+
+                if ( toolchain instanceof DefaultToolchain )
+                {
+                    DefaultToolchain defaultToolchain = (DefaultToolchain) 
toolchain;
+                    javaVersion9 = defaultToolchain.matchesRequirements( 
JAVA_9_MATCHER )
+                                             || 
defaultToolchain.matchesRequirements( JAVA_9_MATCHER_OLD_NOTATION );
+                }
+
+                if ( !javaVersion9 )
+                {
+                    javaVersion9 = isJava9AtLeast( jvmToUse );
+                }
+
+                return new JdkAttributes( jvmToUse, javaVersion9 );
+            }
         }
 
-        return jvmToUse;
-    }
+        // use the same JVM as the one used to run Maven (the "java.home" one)
+        String jvmToUse = System.getProperty( "java.home" ) + File.separator + 
"bin" + File.separator + "java";
+        getConsoleLogger().debug( "Using JVM: " + jvmToUse + " with Java 
version " + JAVA_RECENT.toString() );
 
+        return new JdkAttributes( jvmToUse, isJavaVersionAtLeast( JAVA_9 ) );
+    }
 
     private Artifact getSurefireBooterArtifact()
     {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..65b1254
--- /dev/null
+++ 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java
@@ -0,0 +1,48 @@
+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 static 
org.apache.maven.surefire.util.internal.ObjectUtils.requireNonNull;
+
+/**
+ * @author <a href="mailto:tibordig...@apache.org";>Tibor Digana (tibor17)</a>
+ * @since 2.20.1
+ */
+public final class JdkAttributes
+{
+    private final String jvmExecutable;
+    private final boolean java9AtLeast;
+
+    public JdkAttributes( String jvmExecutable, boolean java9AtLeast )
+    {
+        this.jvmExecutable = requireNonNull( jvmExecutable, "null path to java 
executable" );
+        this.java9AtLeast = java9AtLeast;
+    }
+
+    public String getJvmExecutable()
+    {
+        return jvmExecutable;
+    }
+
+    public boolean isJava9AtLeast()
+    {
+        return java9AtLeast;
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/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 1c7626e..b3b9251 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
@@ -20,9 +20,9 @@ package org.apache.maven.plugin.surefire.booterclient;
  */
 
 import org.apache.maven.plugin.surefire.AbstractSurefireMojo;
+import org.apache.maven.plugin.surefire.JdkAttributes;
 import 
org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
 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;
@@ -42,6 +42,7 @@ import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
 
 import static 
org.apache.maven.plugin.surefire.SurefireHelper.escapeToPlatformPath;
+import static org.apache.maven.shared.utils.StringUtils.join;
 
 /**
  * Configuration for forking tests.
@@ -66,7 +67,7 @@ public class ForkConfiguration
 
     private final Classpath bootClasspathConfiguration;
 
-    private final String jvmExecutable;
+    private final JdkAttributes jdk;
 
     private final Properties modelProperties;
 
@@ -86,14 +87,14 @@ public class ForkConfiguration
 
     @SuppressWarnings( "checkstyle:parameternumber" )
     public ForkConfiguration( Classpath bootClasspathConfiguration, File 
tmpDir, String debugLine,
-                              String jvmExecutable, File workingDirectory, 
Properties modelProperties, String argLine,
+                              JdkAttributes jdk, File workingDirectory, 
Properties modelProperties, String argLine,
                               Map<String, String> environmentVariables, 
boolean debugEnabled, int forkCount,
                               boolean reuseForks, Platform pluginPlatform )
     {
         this.bootClasspathConfiguration = bootClasspathConfiguration;
         this.tempDirectory = tmpDir;
         this.debugLine = debugLine;
-        this.jvmExecutable = jvmExecutable;
+        this.jdk = jdk;
         this.workingDirectory = workingDirectory;
         this.modelProperties = modelProperties;
         this.argLine = argLine;
@@ -131,24 +132,25 @@ public class ForkConfiguration
     }
 
     /**
-     * @param classPath            cla the classpath arguments
-     * @param startupConfiguration The startup configuration
+     * @param classPath            cli the classpath arguments
+     * @param config               The startup configuration
      * @param threadNumber         the thread number, to be the replacement in 
the argLine   @return A commandline
      * @return CommandLine able to flush entire command going to be sent to 
forked JVM
      * @throws org.apache.maven.surefire.booter.SurefireBooterForkException
      *          when unable to perform the fork
      */
-    public OutputStreamFlushableCommandline createCommandLine( List<String> 
classPath,
-                                                               
StartupConfiguration startupConfiguration,
+    public OutputStreamFlushableCommandline createCommandLine( List<String> 
classPath, StartupConfiguration config,
                                                                int 
threadNumber )
-        throws SurefireBooterForkException
+            throws SurefireBooterForkException
     {
-        return createCommandLine( classPath,
-                                  
startupConfiguration.getClassLoaderConfiguration()
-                                      .isManifestOnlyJarRequestedAndUsable(),
-                                  startupConfiguration.isShadefire(), 
startupConfiguration.isProviderMainClass()
-            ? startupConfiguration.getActualClassName()
-            : ForkedBooter.class.getName(), threadNumber );
+        boolean useJar = 
config.getClassLoaderConfiguration().isManifestOnlyJarRequestedAndUsable();
+
+        boolean shadefire = config.isShadefire();
+
+        String providerThatHasMainMethod =
+                config.isProviderMainClass() ? config.getActualClassName() : 
ForkedBooter.class.getName();
+
+        return createCommandLine( classPath, useJar, shadefire, 
providerThatHasMainMethod, threadNumber );
     }
 
     OutputStreamFlushableCommandline createCommandLine( List<String> 
classPath, boolean useJar, boolean shadefire,
@@ -157,13 +159,26 @@ public class ForkConfiguration
     {
         OutputStreamFlushableCommandline cli = new 
OutputStreamFlushableCommandline();
 
-        cli.setExecutable( jvmExecutable );
+        cli.setExecutable( jdk.getJvmExecutable() );
+
+        String jvmArgLine =
+                replaceThreadNumberPlaceholder( stripNewLines( 
replacePropertyExpressions() ), threadNumber );
+
+        if ( jdk.isJava9AtLeast() && !jvmArgLine.contains( "--add-modules" ) )
+        {
+            if ( jvmArgLine.isEmpty() )
+            {
+                jvmArgLine = "--add-modules ALL-SYSTEM";
+            }
+            else
+            {
+                jvmArgLine = "--add-modules ALL-SYSTEM " + jvmArgLine;
+            }
+        }
 
-        if ( argLine != null )
+        if ( !jvmArgLine.isEmpty() )
         {
-            cli.createArg().setLine(
-                   replaceThreadNumberPlaceholder( stripNewLines( 
replacePropertyExpressions( argLine ) ),
-                                                   threadNumber ) );
+            cli.createArg().setLine( jvmArgLine );
         }
 
         for ( Map.Entry<String, String> entry : 
environmentVariables.entrySet() )
@@ -192,7 +207,7 @@ public class ForkConfiguration
         }
         else
         {
-            cli.addEnvironment( "CLASSPATH", StringUtils.join( 
classPath.iterator(), File.pathSeparator ) );
+            cli.addEnvironment( "CLASSPATH", join( classPath.iterator(), 
File.pathSeparator ) );
 
             final String forkedBooter =
                 providerThatHasMainMethod != null ? providerThatHasMainMethod 
: ForkedBooter.class.getName();
@@ -235,11 +250,18 @@ public class ForkConfiguration
      *
      * This allows other plugins to modify or set properties with the changes 
getting picked up by surefire.
      */
-    private String replacePropertyExpressions( String argLine )
+    private String replacePropertyExpressions()
     {
         if ( argLine == null )
         {
-            return null;
+            return "";
+        }
+
+        String resolvedArgLine = argLine.trim();
+
+        if ( resolvedArgLine.isEmpty() )
+        {
+            return "";
         }
 
         for ( final String key : modelProperties.stringPropertyNames() )
@@ -247,11 +269,11 @@ public class ForkConfiguration
             String field = "@{" + key + "}";
             if ( argLine.contains( field ) )
             {
-                argLine = argLine.replace( field, modelProperties.getProperty( 
key, "" ) );
+                resolvedArgLine = resolvedArgLine.replace( field, 
modelProperties.getProperty( key, "" ) );
             }
         }
 
-        return argLine;
+        return resolvedArgLine;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java
 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java
index 60c6dfe..629778b 100644
--- 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java
+++ 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java
@@ -19,7 +19,6 @@ package org.apache.maven.plugin.surefire.report;
  * under the License.
  */
 
-import org.apache.maven.shared.utils.io.IOUtil;
 import org.apache.maven.shared.utils.xml.PrettyPrintXMLWriter;
 import org.apache.maven.shared.utils.xml.XMLWriter;
 import org.apache.maven.surefire.report.ReportEntry;
@@ -42,6 +41,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.StringTokenizer;
 
+import static org.apache.commons.io.IOUtils.closeQuietly;
 import static 
org.apache.maven.plugin.surefire.report.DefaultReporterFactory.TestResultType;
 import static 
org.apache.maven.plugin.surefire.report.FileReporterUtils.stripIllegalFilenameChars;
 import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
@@ -239,7 +239,7 @@ public class StatelessXmlReporter
         }
         finally
         {
-            IOUtil.close( fw );
+            closeQuietly( fw );
         }
     }
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/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 5d970d8..26b8be7 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
@@ -207,7 +207,7 @@ public class BooterDeserializerProviderConfigurationTest
                                                  boolean readTestsFromInStream 
)
         throws IOException
     {
-        final ForkConfiguration forkConfiguration = 
ForkConfigurationTest.getForkConfiguration( null, null );
+        final ForkConfiguration forkConfiguration = 
ForkConfigurationTest.getForkConfiguration( (String) null );
         PropertiesWrapper props = new PropertiesWrapper( new HashMap<String, 
String>() );
         BooterSerializer booterSerializer = new BooterSerializer( 
forkConfiguration );
         Object test;

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/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 0cb292c..035add0 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
@@ -119,7 +119,7 @@ public class BooterDeserializerStartupConfigurationTest
     private StartupConfiguration saveAndReload( StartupConfiguration 
startupConfiguration )
         throws IOException
     {
-        final ForkConfiguration forkConfiguration = 
ForkConfigurationTest.getForkConfiguration( null, null );
+        final ForkConfiguration forkConfiguration = 
ForkConfigurationTest.getForkConfiguration( (String) null );
         PropertiesWrapper props = new PropertiesWrapper( new HashMap<String, 
String>() );
         BooterSerializer booterSerializer = new BooterSerializer( 
forkConfiguration );
         String aTest = "aTest";

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
 
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
index 1e09d6f..b49e164 100644
--- 
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
+++ 
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
@@ -19,29 +19,32 @@ package org.apache.maven.plugin.surefire.booterclient;
  * under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Properties;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.SystemUtils;
+import org.apache.maven.plugin.surefire.JdkAttributes;
 import org.apache.maven.shared.utils.StringUtils;
 import org.apache.maven.shared.utils.cli.Commandline;
 import org.apache.maven.surefire.booter.Classpath;
 import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.junit.Test;
 
-import junit.framework.TestCase;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 public class ForkConfigurationTest
-    extends TestCase
 {
-
+    @Test
     public void 
testCreateCommandLine_UseSystemClassLoaderForkOnce_ShouldConstructManifestOnlyJar()
         throws IOException, SurefireBooterForkException
     {
-        ForkConfiguration config = getForkConfiguration( null, "java" );
+        ForkConfiguration config = getForkConfiguration( (String) null );
         File cpElement = getTempClasspathFile();
 
         Commandline cli =
@@ -51,12 +54,13 @@ public class ForkConfigurationTest
         assertTrue( line.contains( "-jar" ) );
     }
 
+    @Test
     public void testArglineWithNewline()
         throws IOException, SurefireBooterForkException
     {
         // SUREFIRE-657
         File cpElement = getTempClasspathFile();
-        ForkConfiguration forkConfiguration = getForkConfiguration( 
"abc\ndef", null );
+        ForkConfiguration forkConfiguration = getForkConfiguration( "abc\ndef" 
);
 
         final Commandline commandLine =
             forkConfiguration.createCommandLine( Collections.singletonList( 
cpElement.getAbsolutePath() ), false, false,
@@ -64,18 +68,19 @@ public class ForkConfigurationTest
         assertTrue( commandLine.toString().contains( "abc def" ) );
     }
 
+    @Test
     public void 
testCurrentWorkingDirectoryPropagationIncludingForkNumberExpansion()
         throws IOException, SurefireBooterForkException
     {
         // SUREFIRE-1136
         File baseDir =
             new File( FileUtils.getTempDirectory(), "SUREFIRE-1136-" + 
RandomStringUtils.randomAlphabetic( 3 ) );
-        baseDir.mkdirs();
+        assertTrue( baseDir.mkdirs() );
         baseDir.deleteOnExit();
 
         File cwd = new File( baseDir, "fork_${surefire.forkNumber}" );
 
-        ForkConfiguration config = getForkConfiguration( null, "java", 
cwd.getCanonicalFile() );
+        ForkConfiguration config = getForkConfiguration( null, 
cwd.getCanonicalFile() );
         Commandline commandLine = config.createCommandLine( 
Collections.<String>emptyList(), true, false, null, 1 );
 
         File forkDirectory = new File( baseDir, "fork_1" );
@@ -84,20 +89,21 @@ public class ForkConfigurationTest
             commandLine.getShell().getWorkingDirectory().getCanonicalPath() ) 
);
     }
 
+    @Test
     public void testExceptionWhenCurrentDirectoryIsNotRealDirectory()
         throws IOException, SurefireBooterForkException
     {
         // SUREFIRE-1136
         File baseDir =
             new File( FileUtils.getTempDirectory(), "SUREFIRE-1136-" + 
RandomStringUtils.randomAlphabetic( 3 ) );
-        baseDir.mkdirs();
+        assertTrue( baseDir.mkdirs() );
         baseDir.deleteOnExit();
 
         File cwd = new File( baseDir, "cwd.txt" );
         FileUtils.touch( cwd );
         cwd.deleteOnExit();
 
-        ForkConfiguration config = getForkConfiguration( null, "java", 
cwd.getCanonicalFile() );
+        ForkConfiguration config = getForkConfiguration( null, 
cwd.getCanonicalFile() );
 
         try
         {
@@ -114,19 +120,20 @@ public class ForkConfigurationTest
         fail();
     }
 
+    @Test
     public void testExceptionWhenCurrentDirectoryCannotBeCreated()
         throws IOException, SurefireBooterForkException
     {
         // SUREFIRE-1136
         File baseDir =
             new File( FileUtils.getTempDirectory(), "SUREFIRE-1136-" + 
RandomStringUtils.randomAlphabetic( 3 ) );
-        baseDir.mkdirs();
+        assertTrue( baseDir.mkdirs() );
         baseDir.deleteOnExit();
 
         // NULL is invalid for JDK starting from 1.7.60 - 
https://github.com/openjdk-mirror/jdk/commit/e5389115f3634d25d101e2dcc71f120d4fd9f72f
         // ? character is invalid on Windows, seems to be imposable to create 
invalid directory using Java on Linux
         File cwd = new File( baseDir, "?\u0000InvalidDirectoryName" );
-        ForkConfiguration config = getForkConfiguration( null, "java", 
cwd.getAbsoluteFile() );
+        ForkConfiguration config = getForkConfiguration( null, 
cwd.getAbsoluteFile() );
 
         try
         {
@@ -152,17 +159,31 @@ public class ForkConfigurationTest
         return cpElement;
     }
 
-    public static ForkConfiguration getForkConfiguration( String argLine, 
String jvm )
+    public static ForkConfiguration getForkConfiguration( File javaExec )
+            throws IOException
+    {
+        return getForkConfiguration( null, javaExec.getAbsolutePath(), new 
File( "." ).getCanonicalFile() );
+    }
+
+    public static ForkConfiguration getForkConfiguration( String argLine )
         throws IOException
     {
-        return getForkConfiguration( argLine, jvm, new File( "." 
).getCanonicalFile() );
+        File jvm = new File( new File( System.getProperty( "java.home" ), 
"bin" ), "java" );
+        return getForkConfiguration( argLine, jvm.getAbsolutePath(), new File( 
"." ).getCanonicalFile() );
+    }
+
+    public static ForkConfiguration getForkConfiguration( String argLine, File 
cwd )
+            throws IOException
+    {
+        File jvm = new File( new File( System.getProperty( "java.home" ), 
"bin" ), "java" );
+        return getForkConfiguration( argLine, jvm.getAbsolutePath(), cwd );
     }
 
-    public static ForkConfiguration getForkConfiguration( String argLine, 
String jvm, File cwd )
+    private static ForkConfiguration getForkConfiguration( String argLine, 
String jvm, File cwd )
         throws IOException
     {
-        return new ForkConfiguration( Classpath.emptyClasspath(), null, null, 
jvm, cwd, new Properties(), argLine, null,
-                                      false, 1, false, new Platform() );
+        return new ForkConfiguration( Classpath.emptyClasspath(), null, null, 
new JdkAttributes( jvm, false ),
+                                            cwd, new Properties(), argLine, 
null, false, 1, false, new Platform() );
     }
 
     // based on 
http://stackoverflow.com/questions/2591083/getting-version-of-java-in-runtime
@@ -170,6 +191,6 @@ public class ForkConfigurationTest
     {
         String[] javaVersionElements = System.getProperty( 
"java.runtime.version" ).split( "\\.|_|-b" );
         return Integer.valueOf( javaVersionElements[1] ) >= major
-            && Integer.valueOf( javaVersionElements[4] ) >= update;
+            && Integer.valueOf( javaVersionElements[3] ) >= update;
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-surefire-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/maven-surefire-plugin/pom.xml b/maven-surefire-plugin/pom.xml
index 2a186e3..96a1720 100644
--- a/maven-surefire-plugin/pom.xml
+++ b/maven-surefire-plugin/pom.xml
@@ -86,6 +86,7 @@
       </plugin>
       <plugin>
         <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.6</version>
         <executions>
           <execution>
             <id>build-site</id>
@@ -103,32 +104,6 @@
           </execution>
         </executions>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <executions>
-          <execution>
-            <phase>package</phase>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-            <configuration>
-              <minimizeJar>true</minimizeJar>
-              <artifactSet>
-                <includes>
-                  <include>org.apache.maven.shared:maven-shared-utils</include>
-                </includes>
-              </artifactSet>
-              <relocations>
-                <relocation>
-                  <pattern>org.apache.maven.shared</pattern>
-                  
<shadedPattern>org.apache.maven.surefire.shade.org.apache.maven.shared</shadedPattern>
-                </relocation>
-              </relocations>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
     </plugins>
   </build>
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-surefire-plugin/src/site/markdown/java9.md
----------------------------------------------------------------------
diff --git a/maven-surefire-plugin/src/site/markdown/java9.md 
b/maven-surefire-plugin/src/site/markdown/java9.md
new file mode 100644
index 0000000..96bc9a8
--- /dev/null
+++ b/maven-surefire-plugin/src/site/markdown/java9.md
@@ -0,0 +1,92 @@
+<!--
+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.
+-->
+
+Java 9 in JAVA_HOME
+========================
+
+    $ export JAVA_HOME=/path/to/jdk9
+    $ mvn test
+
+The plugin will automatically add `--add-modules ALL-SYSTEM` on JVM argument 
in CLI (unless already specified by user)
+and all Java 9 API is provided to run your tests.
+
+
+Java 9 in configuration of plugin
+========================
+
+The plugin provides you with configuration parameter `jvm` which can point to 
path of executable Java in JDK, e.g.:
+
+    <configuration>
+        <jvm>/path/to/jdk9/bin/java</jvm>
+    </configuration>
+
+Now you can run the build with tests on the top of Java 9.
+
+
+Maven Toolchains with JDK 9
+========================
+
+This is an example on Windows to run unit tests with custom path to Toolchain 
**(-t ...)**.
+
+    $ mvn -t D:\.m2\toolchains.xml test
+    
+Without **(-t ...)** the Toolchain should be located in 
**${user.home}/.m2/toolchains.xml**.
+
+The content of **toolchains.xml** would become as follows however multiple 
different JDKs can be specified.
+
+    <toolchains xmlns="http://maven.apache.org/POM/4.0.0";
+                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+                xsi:schemaLocation="http://maven.apache.org/TOOLCHAINS/1.1.0 
https://maven.apache.org/xsd/toolchains-1.1.0.xsd";>
+      <toolchain>
+        <type>jdk</type>
+        <provides>
+          <version>9</version>
+          <vendor>oracle</vendor>
+          <id>jdk9</id>
+        </provides>
+        <configuration>
+          <jdkHome>/path/to/jdk9</jdkHome>
+        </configuration>
+      </toolchain>
+    </toolchains>
+
+Your POM should specify the plugin which activates only particular JDK in 
*toolchains.xml* which specifies version **9**:
+
+    <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-toolchains-plugin</artifactId>
+        <version>1.1</version>
+        <executions>
+          <execution>
+            <phase>validate</phase>
+            <goals>
+              <goal>toolchain</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <toolchains>
+            <jdk>
+              <version>9</version>
+            </jdk>
+          </toolchains>
+        </configuration>
+    </plugin>
+
+Now you can run the build with tests on the top of Java 9.

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xjb
----------------------------------------------------------------------
diff --git a/maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xjb 
b/maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xjb
deleted file mode 100644
index 1e076d3..0000000
--- a/maven-surefire-plugin/src/site/resources/xsd/failsafe-summary.xjb
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!--
-~ 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.
--->
-<jxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema";
-        xmlns:jxb="http://java.sun.com/xml/ns/jaxb";
-        version="2.0">
-    <jxb:bindings schemaLocation="failsafe-summary.xsd">
-        <jxb:bindings 
node="//xsd:simpleType[@name='errorType']/xsd:restriction/xsd:enumeration[@id='FAILURE']">
-            <jxb:typesafeEnumMember name="FAILURE"/>
-        </jxb:bindings>
-        <jxb:bindings 
node="//xsd:simpleType[@name='errorType']/xsd:restriction/xsd:enumeration[@id='NO_TESTS']">
-            <jxb:typesafeEnumMember name="NO_TESTS"/>
-        </jxb:bindings>
-    </jxb:bindings>
-</jxb:bindings>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/maven-surefire-plugin/src/site/site.xml
----------------------------------------------------------------------
diff --git a/maven-surefire-plugin/src/site/site.xml 
b/maven-surefire-plugin/src/site/site.xml
index 7e8d49c..2d2e95a 100644
--- a/maven-surefire-plugin/src/site/site.xml
+++ b/maven-surefire-plugin/src/site/site.xml
@@ -56,6 +56,7 @@
       <item name="Fork Options and Parallel Test Execution" 
href="examples/fork-options-and-parallel-execution.html"/>
       <item name="Using Console Logs" href="examples/logging.html"/>
       <item name="Shutdown of Forked JVM" href="examples/shutdown.html"/>
+      <item name="Run tests with Java 9" href="java9.html"/>
     </menu>
   </body>
 </project>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 6ba5602..0f64b4a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,7 +97,7 @@
     
<maven.surefire.scm.devConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven-surefire.git</maven.surefire.scm.devConnection>
     <maven.site.path>surefire-archives/surefire-LATEST</maven.site.path>
     <!-- Override with Jigsaw JRE 9 -->
-    <test.jre>${java.home}/..</test.jre>
+    <jdk.home>${java.home}/..</jdk.home>
   </properties>
 
   <dependencyManagement>
@@ -218,6 +218,11 @@
         <version>${mavenVersion}</version>
       </dependency>
       <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-settings</artifactId>
+        <version>${mavenVersion}</version>
+      </dependency>
+      <dependency>
         <groupId>org.apache.maven.shared</groupId>
         <artifactId>maven-shared-utils</artifactId>
         <version>${mavenSharedUtilsVersion}</version>
@@ -245,6 +250,22 @@
         </exclusions>
       </dependency>
       <dependency>
+        <groupId>org.powermock</groupId>
+        <artifactId>powermock-mockito-release-full</artifactId>
+        <version>1.6.4</version>
+        <classifier>full</classifier>
+        <exclusions>
+          <exclusion>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.12</version>
@@ -399,12 +420,12 @@
         </plugin>
         <plugin>
           <artifactId>maven-invoker-plugin</artifactId>
-          <version>2.0.0</version>
+          <version>3.0.1</version>
         </plugin>
         <plugin>
           <groupId>org.jacoco</groupId>
           <artifactId>jacoco-maven-plugin</artifactId>
-          <version>0.7.8</version>
+          <version>0.7.9</version>
           <configuration>
             <includes>
               <include>**/failsafe/*</include>
@@ -420,6 +441,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-enforcer-plugin</artifactId>
+        <version>3.0.0-M1</version>
         <executions>
           <execution>
             <id>enforce-java</id>
@@ -429,7 +451,9 @@
             <configuration>
               <rules>
                 <requireJavaVersion>
-                  <version>[1.8.0,)</version>
+                  <!-- We use JDK 1.8 to check -Xdoclint:all at compile time 
but with javac -source 1.6 -target 1.6 -->
+                  <!-- enforcer:1.3.1 fails on jdk9. 3.0.0-M1 does not but 
surefire:12.2.4 crashes later. -->
+                  <version>[1.8, 1.9)</version>
                 </requireJavaVersion>
               </rules>
             </configuration>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/surefire-api/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-api/pom.xml b/surefire-api/pom.xml
index ec5c664..7b29c6d 100644
--- a/surefire-api/pom.xml
+++ b/surefire-api/pom.xml
@@ -52,7 +52,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <jvm>${test.jre}/bin/java</jvm>
+          <jvm>${jdk.home}/bin/java</jvm>
           <redirectTestOutputToFile>true</redirectTestOutputToFile>
           <includes>
             <include>**/JUnit4SuiteTest.java</include>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/cdc7b64c/surefire-booter/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-booter/pom.xml b/surefire-booter/pom.xml
index 8fdaf7e..b564fa4 100644
--- a/surefire-booter/pom.xml
+++ b/surefire-booter/pom.xml
@@ -55,6 +55,12 @@
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-mockito-release-full</artifactId>
+      <classifier>full</classifier>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
@@ -85,7 +91,7 @@
           </dependency>
         </dependencies>
         <configuration>
-          <jvm>${test.jre}/bin/java</jvm>
+          <jvm>${jdk.home}/bin/java</jvm>
           <redirectTestOutputToFile>true</redirectTestOutputToFile>
           <includes>
             <include>**/JUnit4SuiteTest.java</include>

Reply via email to