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 2019/08/29 17:31:54 UTC

[maven-surefire] branch maven2surefire-jvm-communication updated: proposed abstraction for Enrico's implementation

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

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


The following commit(s) were added to refs/heads/maven2surefire-jvm-communication by this push:
     new 9a7d2a2  proposed abstraction for Enrico's implementation
9a7d2a2 is described below

commit 9a7d2a2d39bdf0860b282faf541bece01a4a708d
Author: tibordigana <ti...@apache.org>
AuthorDate: Thu Aug 29 19:31:34 2019 +0200

    proposed abstraction for Enrico's implementation
---
 .../plugin/surefire/AbstractSurefireMojo.java      | 14 +++-
 .../AbstractClasspathForkConfiguration.java        |  6 +-
 .../booterclient/ClasspathForkConfiguration.java   |  6 +-
 .../booterclient/DefaultForkConfiguration.java     | 13 ++-
 .../surefire/booterclient/ForkConfiguration.java   |  2 +
 .../plugin/surefire/booterclient/ForkStarter.java  | 33 +++++---
 .../booterclient/JarManifestForkConfiguration.java |  6 +-
 .../ModularClasspathForkConfiguration.java         |  6 +-
 ...InputStream.java => AbstractCommandReader.java} | 19 +++--
 ...ommandStream.java => DefaultCommandReader.java} |  6 +-
 .../DifferedChannelCommandSender.java              |  2 +-
 ...nder.java => ExecutableCommandlineFactory.java} | 15 ++--
 .../lazytestprovider/TestLessInputStream.java      |  4 +-
 .../lazytestprovider/TestProvidingInputStream.java |  4 +-
 ...eCommandline.java => AbstractEventHandler.java} |  8 +-
 .../booterclient/output/ExecutableCommandline.java | 14 +++-
 .../output/NetworkingProcessExecutor.java          | 28 ++++---
 .../booterclient/output/PipeProcessExecutor.java   | 93 +++++++++++++++++++---
 .../booterclient/DefaultForkConfigurationTest.java | 44 +++++-----
 .../ModularClasspathForkConfigurationTest.java     |  2 +-
 .../apache/maven/surefire/booter/ForkedBooter.java |  2 +-
 .../surefire/extensions/ForkedChannelServer.java   |  2 +-
 22 files changed, 226 insertions(+), 103 deletions(-)

diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index e2c69b6..ef989b2 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
@@ -25,6 +25,7 @@ import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.ArtifactHandler;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.ExecutableCommandlineFactory;
 import org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter;
 import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
 import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
@@ -2261,6 +2262,10 @@ public abstract class AbstractSurefireMojo
 
         Classpath bootClasspath = getArtifactClasspath( shadeFire != null ? shadeFire : surefireBooterArtifact );
 
+        //todo Enrico, here should be implementation for pipes and NettyIO depending on MOJO configuration
+        // todo we will create a new @Parameter with POJO object of complex configuration for TCP/IP
+        ExecutableCommandlineFactory executableCommandlineFactory = null;
+
         if ( canExecuteProviderWithModularPath( platform ) )
         {
             return new ModularClasspathForkConfiguration( bootClasspath,
@@ -2274,7 +2279,8 @@ public abstract class AbstractSurefireMojo
                     getEffectiveForkCount(),
                     reuseForks,
                     platform,
-                    getConsoleLogger() );
+                    getConsoleLogger(),
+                    executableCommandlineFactory );
         }
         else if ( getClassLoaderConfiguration().isManifestOnlyJarRequestedAndUsable() )
         {
@@ -2289,7 +2295,8 @@ public abstract class AbstractSurefireMojo
                     getEffectiveForkCount(),
                     reuseForks,
                     platform,
-                    getConsoleLogger() );
+                    getConsoleLogger(),
+                    executableCommandlineFactory );
         }
         else
         {
@@ -2304,7 +2311,8 @@ public abstract class AbstractSurefireMojo
                     getEffectiveForkCount(),
                     reuseForks,
                     platform,
-                    getConsoleLogger() );
+                    getConsoleLogger(),
+                    executableCommandlineFactory );
         }
     }
 
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
index 6c57ebc..8d867cd 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.maven.plugin.surefire.booterclient;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.ExecutableCommandlineFactory;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.booter.Classpath;
 
@@ -48,10 +49,11 @@ abstract class AbstractClasspathForkConfiguration
                                         int forkCount,
                                         boolean reuseForks,
                                         @Nonnull Platform pluginPlatform,
-                                        @Nonnull ConsoleLogger log )
+                                        @Nonnull ConsoleLogger log,
+                                        @Nonnull ExecutableCommandlineFactory executableCommandlineFactory )
     {
         super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
-                environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+                environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log, executableCommandlineFactory );
     }
 
     @Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
index cf6c67e..81864f3 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.maven.plugin.surefire.booterclient;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.ExecutableCommandlineFactory;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.booter.Classpath;
@@ -46,10 +47,11 @@ public final class ClasspathForkConfiguration
                                        @Nonnull Properties modelProperties, @Nullable String argLine,
                                        @Nonnull Map<String, String> environmentVariables, boolean debug, int forkCount,
                                        boolean reuseForks, @Nonnull Platform pluginPlatform,
-                                       @Nonnull ConsoleLogger log )
+                                       @Nonnull ConsoleLogger log,
+                                       @Nonnull ExecutableCommandlineFactory executableCommandlineFactory )
     {
         super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
-                environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+                environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log, executableCommandlineFactory );
     }
 
     @Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
index fa99451..1caa71a 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
@@ -20,6 +20,7 @@ package org.apache.maven.plugin.surefire.booterclient;
  */
 
 import org.apache.maven.plugin.surefire.JdkAttributes;
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.ExecutableCommandlineFactory;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.booter.AbstractPathConfiguration;
@@ -64,6 +65,7 @@ public abstract class DefaultForkConfiguration
     private final boolean reuseForks;
     @Nonnull private final Platform pluginPlatform;
     @Nonnull private final ConsoleLogger log;
+    @Nonnull private final ExecutableCommandlineFactory executableCommandlineFactory;
 
     @SuppressWarnings( "checkstyle:parameternumber" )
     protected DefaultForkConfiguration( @Nonnull Classpath booterClasspath,
@@ -77,7 +79,8 @@ public abstract class DefaultForkConfiguration
                                      int forkCount,
                                      boolean reuseForks,
                                      @Nonnull Platform pluginPlatform,
-                                     @Nonnull ConsoleLogger log )
+                                     @Nonnull ConsoleLogger log,
+                                     @Nonnull ExecutableCommandlineFactory executableCommandlineFactory )
     {
         this.booterClasspath = booterClasspath;
         this.tempDirectory = tempDirectory;
@@ -91,6 +94,7 @@ public abstract class DefaultForkConfiguration
         this.reuseForks = reuseForks;
         this.pluginPlatform = pluginPlatform;
         this.log = log;
+        this.executableCommandlineFactory = executableCommandlineFactory;
     }
 
     protected abstract void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@@ -105,6 +109,13 @@ public abstract class DefaultForkConfiguration
         return jvmArgLine;
     }
 
+    @Nonnull
+    @Override
+    public final ExecutableCommandlineFactory getExecutableCommandlineFactory()
+    {
+        return executableCommandlineFactory;
+    }
+
     /**
      * @param config       The startup configuration
      * @param forkNumber   index of forked JVM, to be the replacement in the argLine
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 d45d13d..881d542 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,6 +20,7 @@ package org.apache.maven.plugin.surefire.booterclient;
  */
 
 import org.apache.maven.plugin.surefire.JdkAttributes;
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.ExecutableCommandlineFactory;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
 import org.apache.maven.surefire.booter.Classpath;
 import org.apache.maven.surefire.booter.ForkedBooter;
@@ -39,6 +40,7 @@ public abstract class ForkConfiguration
 {
     static final String DEFAULT_PROVIDER_CLASS = ForkedBooter.class.getName();
 
+    @Nonnull public abstract ExecutableCommandlineFactory getExecutableCommandlineFactory();
     @Nonnull public abstract File getTempDirectory();
     @Nullable protected abstract String getDebugLine();
     @Nonnull protected abstract File getWorkingDirectory();
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
index eb10582..fd06a6c 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
@@ -22,11 +22,12 @@ package org.apache.maven.plugin.surefire.booterclient;
 import org.apache.maven.plugin.surefire.CommonReflector;
 import org.apache.maven.plugin.surefire.StartupReportConfiguration;
 import org.apache.maven.plugin.surefire.SurefireProperties;
-import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.DifferedChannelCommandSender;
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractCommandReader;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.NotifiableTestStream;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestProvidingInputStream;
+import org.apache.maven.plugin.surefire.booterclient.output.ExecutableCommandline;
 import org.apache.maven.plugin.surefire.booterclient.output.ForkClient;
 import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
 import org.apache.maven.plugin.surefire.booterclient.output.NativeStdErrStreamConsumer;
@@ -54,7 +55,6 @@ import javax.annotation.Nonnull;
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Map;
@@ -76,7 +76,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import static java.lang.StrictMath.min;
 import static java.lang.System.currentTimeMillis;
 import static java.lang.Thread.currentThread;
-import static java.nio.charset.StandardCharsets.ISO_8859_1;
 import static java.util.Collections.addAll;
 import static java.util.concurrent.Executors.newScheduledThreadPool;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -88,7 +87,6 @@ import static org.apache.maven.plugin.surefire.booterclient.ForkNumberBucket.dra
 import static org.apache.maven.plugin.surefire.booterclient.ForkNumberBucket.returnNumber;
 import static org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream
                       .TestLessInputStreamBuilder;
-import static org.apache.maven.shared.utils.cli.CommandLineUtils.executeCommandLineAsCallable;
 import static org.apache.maven.shared.utils.cli.ShutdownHookUtils.addShutDownHook;
 import static org.apache.maven.shared.utils.cli.ShutdownHookUtils.removeShutdownHook;
 import static org.apache.maven.surefire.booter.SystemPropertyManager.writePropertiesFile;
@@ -282,7 +280,10 @@ public class ForkStarter
             defaultReporterFactories.add( forkedReporterFactory );
             ForkClient forkClient =
                     new ForkClient( forkedReporterFactory, stream, log, new AtomicBoolean(), forkNumber );
-            return fork( null, props, forkClient, effectiveSystemProperties, forkNumber, stream, false );
+            ExecutableCommandline<?> executableCommandline =
+                    forkConfiguration.getExecutableCommandlineFactory().createExecutableCommandline( stream );
+            return fork( null, props, forkClient, effectiveSystemProperties, forkNumber, stream,
+                    executableCommandline, false );
         }
         finally
         {
@@ -371,8 +372,12 @@ public class ForkStarter
                         Map<String, String> providerProperties = providerConfiguration.getProviderProperties();
                         try
                         {
+                            ExecutableCommandline<?> executableCommandline =
+                                    forkConfiguration.getExecutableCommandlineFactory()
+                                            .createExecutableCommandline( testProvidingInputStream );
                             return fork( null, new PropertiesWrapper( providerProperties ), forkClient,
-                                    effectiveSystemProperties, forkNumber, testProvidingInputStream, true );
+                                    effectiveSystemProperties, forkNumber, testProvidingInputStream,
+                                    executableCommandline, true );
                         }
                         finally
                         {
@@ -444,9 +449,13 @@ public class ForkStarter
                         TestLessInputStream stream = builder.build();
                         try
                         {
+                            ExecutableCommandline<?> executableCommandline =
+                                    forkConfiguration.getExecutableCommandlineFactory()
+                                            .createExecutableCommandline( stream );
                             return fork( testSet,
                                          new PropertiesWrapper( providerConfiguration.getProviderProperties() ),
-                                         forkClient, effectiveSystemProperties, forkNumber, stream, false );
+                                         forkClient, effectiveSystemProperties, forkNumber, stream,
+                                         executableCommandline, false );
                         }
                         finally
                         {
@@ -542,7 +551,8 @@ public class ForkStarter
 
     private RunResult fork( Object testSet, KeyValueSource providerProperties, ForkClient forkClient,
                             SurefireProperties effectiveSystemProperties, int forkNumber,
-                            DifferedChannelCommandSender commandSender, boolean readTestsFromInStream )
+                            AbstractCommandReader commandSender, ExecutableCommandline<?> executableCommandline,
+                            boolean readTestsFromInStream )
         throws SurefireBooterForkException
     {
         final String tempDir;
@@ -553,6 +563,8 @@ public class ForkStarter
             tempDir = forkConfiguration.getTempDirectory().getCanonicalPath();
             BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration );
             Long pluginPid = forkConfiguration.getPluginPlatform().getPluginPid();
+
+            // todo Enrico, add the socket config in providerProperties. The fork VM will read it and connect.
             surefireProperties = booterSerializer.serialize( providerProperties, providerConfiguration,
                     startupConfiguration, testSet, readTestsFromInStream, pluginPid, forkNumber );
 
@@ -604,9 +616,8 @@ public class ForkStarter
             NativeStdErrStreamConsumer stdErrConsumer =
                     new NativeStdErrStreamConsumer( forkClient.getDefaultReporterFactory() );
 
-            CommandLineCallable future =
-                    executeCommandLineAsCallable( cli, (InputStream) commandSender, threadedStreamConsumer,
-                                                        stdErrConsumer, 0, closer, ISO_8859_1 );
+            CommandLineCallable future = executableCommandline.executeCommandLineAsCallable( cli, commandSender,
+                    threadedStreamConsumer, /*todo*/stdOut, stdErrConsumer, closer );
 
             currentForkClients.add( forkClient );
 
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
index 1a3dd4f..6c4253f 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.maven.plugin.surefire.booterclient;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.ExecutableCommandlineFactory;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
 import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
@@ -64,10 +65,11 @@ public final class JarManifestForkConfiguration
                                          @Nonnull Properties modelProperties, @Nullable String argLine,
                                          @Nonnull Map<String, String> environmentVariables, boolean debug,
                                          int forkCount, boolean reuseForks, @Nonnull Platform pluginPlatform,
-                                         @Nonnull ConsoleLogger log )
+                                         @Nonnull ConsoleLogger log,
+                                         @Nonnull ExecutableCommandlineFactory executableCommandlineFactory )
     {
         super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
-                environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+                environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log, executableCommandlineFactory );
     }
 
     @Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfiguration.java
index 48e74d9..29ff3f1 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.maven.plugin.surefire.booterclient;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.ExecutableCommandlineFactory;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
 import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
@@ -71,10 +72,11 @@ public class ModularClasspathForkConfiguration
                                               @Nonnegative int forkCount,
                                               boolean reuseForks,
                                               @Nonnull Platform pluginPlatform,
-                                              @Nonnull ConsoleLogger log )
+                                              @Nonnull ConsoleLogger log,
+                                              @Nonnull ExecutableCommandlineFactory executableCommandlineFactory )
     {
         super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
-                environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+                environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log, executableCommandlineFactory );
     }
 
     @Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractForkInputStream.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandReader.java
similarity index 78%
rename from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractForkInputStream.java
rename to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandReader.java
index 6bc8cb8..797753d 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractForkInputStream.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandReader.java
@@ -25,18 +25,27 @@ import java.io.InputStream;
 import static java.util.Objects.requireNonNull;
 
 /**
- * Reader stream sends bytes to forked jvm std-{@link InputStream input-stream}.
+ * Reader stream sends bytes to the forked jvm std-input-stream.
  *
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
  * @since 2.19
  */
-public abstract class AbstractForkInputStream
-    extends InputStream
+public abstract class AbstractCommandReader
     implements DifferedChannelCommandSender
 {
     private volatile FlushReceiverProvider flushReceiverProvider;
 
     /**
+     * Waits for the next command and
+     * reads complete stream of encoded {@link org.apache.maven.surefire.booter.MasterProcessCommand command}.
+     *
+     * @return encoded command, or null if closed
+     */
+    public abstract byte[] readNextCommand();
+    public abstract void close();
+    public abstract boolean isClosed();
+
+    /**
      * @param flushReceiverProvider the provider for a flush receiver.
      */
     @Override
@@ -45,7 +54,7 @@ public abstract class AbstractForkInputStream
         this.flushReceiverProvider = requireNonNull( flushReceiverProvider );
     }
 
-    protected boolean tryFlush()
+    protected void tryFlush()
         throws IOException
     {
         if ( flushReceiverProvider != null )
@@ -54,9 +63,7 @@ public abstract class AbstractForkInputStream
             if ( flushReceiver != null )
             {
                 flushReceiver.flush();
-                return true;
             }
         }
-        return false;
     }
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandStream.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefaultCommandReader.java
similarity index 96%
rename from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandStream.java
rename to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefaultCommandReader.java
index 31b56c4..b54b16e 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandStream.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefaultCommandReader.java
@@ -31,14 +31,12 @@ import java.io.IOException;
  * @since 2.19
  * @see org.apache.maven.surefire.booter.Command
  */
-public abstract class AbstractCommandStream
-    extends AbstractForkInputStream
+public abstract class DefaultCommandReader
+        extends AbstractCommandReader
 {
     private byte[] currentBuffer;
     private int currentPos;
 
-    protected abstract boolean isClosed();
-
     /**
      * Opposite to {@link #isClosed()}.
      * @return {@code true} if not closed
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DifferedChannelCommandSender.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DifferedChannelCommandSender.java
index 4373b9e..11fd9f3 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DifferedChannelCommandSender.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DifferedChannelCommandSender.java
@@ -25,7 +25,7 @@ import java.io.Closeable;
 
 /**
  * Physical implementation of command sender.<br>
- * Instance of {@link AbstractForkInputStream} (namely {@link TestLessInputStream} or {@link TestProvidingInputStream})
+ * Instance of {@link AbstractCommandReader} (namely {@link TestLessInputStream} or {@link TestProvidingInputStream})
  * or the implementation of {@link ForkedChannelServer} (supported by MOJO plugin configuration).
  *
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DifferedChannelCommandSender.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/ExecutableCommandlineFactory.java
similarity index 65%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DifferedChannelCommandSender.java
copy to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/ExecutableCommandlineFactory.java
index 4373b9e..824ea1a 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DifferedChannelCommandSender.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/ExecutableCommandlineFactory.java
@@ -19,20 +19,17 @@ package org.apache.maven.plugin.surefire.booterclient.lazytestprovider;
  * under the License.
  */
 
-import org.apache.maven.surefire.extensions.ForkedChannelServer;
+import org.apache.maven.plugin.surefire.booterclient.output.ExecutableCommandline;
 
-import java.io.Closeable;
+import javax.annotation.Nonnull;
 
 /**
- * Physical implementation of command sender.<br>
- * Instance of {@link AbstractForkInputStream} (namely {@link TestLessInputStream} or {@link TestProvidingInputStream})
- * or the implementation of {@link ForkedChannelServer} (supported by MOJO plugin configuration).
- *
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
  * @since 3.0.0-M4
  */
-public interface DifferedChannelCommandSender
-    extends NotifiableTestStream, Closeable
+public interface ExecutableCommandlineFactory
 {
-    void setFlushReceiverProvider( FlushReceiverProvider flushReceiverProvider );
+    //todo Enrico, the parameter is not needed in Pipes. It is needed in TCP/IP
+    @Nonnull
+    ExecutableCommandline createExecutableCommandline( AbstractCommandReader forkInputStream );
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStream.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStream.java
index 3014486..d8e72b7 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStream.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStream.java
@@ -45,7 +45,7 @@ import static org.apache.maven.surefire.booter.Command.toShutdown;
  * @since 2.19
  */
 public final class TestLessInputStream
-    extends AbstractCommandStream
+        extends DefaultCommandReader
 {
     private final Semaphore barrier = new Semaphore( 0 );
 
@@ -108,7 +108,7 @@ public final class TestLessInputStream
     }
 
     @Override
-    protected boolean isClosed()
+    public boolean isClosed()
     {
         return closed.get();
     }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStream.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStream.java
index 3af1cfe..a8392c9 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStream.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStream.java
@@ -51,7 +51,7 @@ import static org.apache.maven.surefire.booter.Command.toShutdown;
  * @author Tibor Digana (tibor17)
  */
 public final class TestProvidingInputStream
-    extends AbstractCommandStream
+        extends DefaultCommandReader
 {
     private final Semaphore barrier = new Semaphore( 0 );
 
@@ -146,7 +146,7 @@ public final class TestProvidingInputStream
     }
 
     @Override
-    protected boolean isClosed()
+    public boolean isClosed()
     {
         return closed.get();
     }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ExecutableCommandline.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/AbstractEventHandler.java
similarity index 72%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ExecutableCommandline.java
copy to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/AbstractEventHandler.java
index 67e56bb..2f56055 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ExecutableCommandline.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/AbstractEventHandler.java
@@ -19,14 +19,10 @@ package org.apache.maven.plugin.surefire.booterclient.output;
  * under the License.
  */
 
-import org.apache.maven.shared.utils.cli.CommandLineCallable;
-import org.apache.maven.shared.utils.cli.Commandline;
-import org.apache.maven.shared.utils.cli.StreamConsumer;
-
 /**
  *
  */
-public interface ExecutableCommandline
+abstract class AbstractEventHandler<T>
 {
-    CommandLineCallable executeCommandLineAsCallable( Commandline cli, StreamConsumer stdOut, StreamConsumer stdErr );
+    abstract void handleEvent( T event );
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ExecutableCommandline.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ExecutableCommandline.java
index 67e56bb..f53a9a1 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ExecutableCommandline.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ExecutableCommandline.java
@@ -19,14 +19,24 @@ package org.apache.maven.plugin.surefire.booterclient.output;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractCommandReader;
 import org.apache.maven.shared.utils.cli.CommandLineCallable;
+import org.apache.maven.shared.utils.cli.CommandLineException;
 import org.apache.maven.shared.utils.cli.Commandline;
 import org.apache.maven.shared.utils.cli.StreamConsumer;
 
+import javax.annotation.Nonnull;
+
 /**
  *
  */
-public interface ExecutableCommandline
+public interface ExecutableCommandline<T>
 {
-    CommandLineCallable executeCommandLineAsCallable( Commandline cli, StreamConsumer stdOut, StreamConsumer stdErr );
+    @Nonnull CommandLineCallable executeCommandLineAsCallable( @Nonnull Commandline cli,
+                                                               @Nonnull AbstractCommandReader commands,
+                                                               @Nonnull AbstractEventHandler<T> events,
+                                                               StreamConsumer stdOut,
+                                                               StreamConsumer stdErr,
+                                                               @Nonnull Runnable runAfterProcessTermination )
+            throws CommandLineException;
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NetworkingProcessExecutor.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NetworkingProcessExecutor.java
index 1da7063..56a1b22 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NetworkingProcessExecutor.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NetworkingProcessExecutor.java
@@ -19,10 +19,16 @@ package org.apache.maven.plugin.surefire.booterclient.output;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractCommandReader;
 import org.apache.maven.shared.utils.cli.CommandLineCallable;
+import org.apache.maven.shared.utils.cli.CommandLineException;
+import org.apache.maven.shared.utils.cli.CommandLineUtils;
 import org.apache.maven.shared.utils.cli.Commandline;
 import org.apache.maven.shared.utils.cli.StreamConsumer;
-import org.apache.maven.surefire.extensions.ForkedChannelServer;
+
+import javax.annotation.Nonnull;
+
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
 
 /**
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
@@ -31,17 +37,17 @@ import org.apache.maven.surefire.extensions.ForkedChannelServer;
 final class NetworkingProcessExecutor
         implements ExecutableCommandline
 {
-    private final ForkedChannelServer forkedChannelServer;
-
-    NetworkingProcessExecutor( ForkedChannelServer forkedChannelServer )
-    {
-        this.forkedChannelServer = forkedChannelServer;
-    }
-
+    @Nonnull
     @Override
-    public CommandLineCallable executeCommandLineAsCallable( Commandline cli,
-                                                             StreamConsumer stdOut, StreamConsumer stdErr )
+    public CommandLineCallable executeCommandLineAsCallable( @Nonnull Commandline cli,
+                                                             @Nonnull AbstractCommandReader commands,
+                                                             @Nonnull AbstractEventHandler events,
+                                                             StreamConsumer stdOut,
+                                                             StreamConsumer stdErr,
+                                                             @Nonnull Runnable runAfterProcessTermination )
+            throws CommandLineException
     {
-        return null;
+        return CommandLineUtils.executeCommandLineAsCallable( cli, null, stdOut, stdErr,
+                0, runAfterProcessTermination, ISO_8859_1 );
     }
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/PipeProcessExecutor.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/PipeProcessExecutor.java
index 71b1a3c..c8704c8 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/PipeProcessExecutor.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/PipeProcessExecutor.java
@@ -19,29 +19,104 @@ package org.apache.maven.plugin.surefire.booterclient.output;
  * under the License.
  */
 
-import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractForkInputStream;
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractCommandReader;
 import org.apache.maven.shared.utils.cli.CommandLineCallable;
+import org.apache.maven.shared.utils.cli.CommandLineException;
 import org.apache.maven.shared.utils.cli.Commandline;
+import org.apache.maven.shared.utils.cli.CommandLineUtils;
 import org.apache.maven.shared.utils.cli.StreamConsumer;
 
+import javax.annotation.Nonnull;
+
+import java.io.InputStream;
+
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
 /**
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
  * @since 3.0.0-M4
  */
 final class PipeProcessExecutor
-    implements ExecutableCommandline
+    implements ExecutableCommandline<String>
 {
-    private final AbstractForkInputStream forkInputStream;
+    @Override
+    @Nonnull
+    public CommandLineCallable executeCommandLineAsCallable( @Nonnull Commandline cli,
+                                                             @Nonnull AbstractCommandReader commands,
+                                                             @Nonnull AbstractEventHandler<String> events,
+                                                             StreamConsumer stdOut,
+                                                             StreamConsumer stdErr,
+                                                             @Nonnull Runnable runAfterProcessTermination )
+            throws CommandLineException
+    {
+        return CommandLineUtils.executeCommandLineAsCallable( cli, new CommandReaderAdapter( commands ),
+                new EventHandlerAdapter( events ), stdErr, 0, runAfterProcessTermination, ISO_8859_1 );
+    }
 
-    PipeProcessExecutor( AbstractForkInputStream forkInputStream )
+    private static class EventHandlerAdapter implements StreamConsumer
     {
-        this.forkInputStream = forkInputStream;
+        private final AbstractEventHandler<String> events;
+
+        private EventHandlerAdapter( AbstractEventHandler<String> events )
+        {
+            this.events = events;
+        }
+
+        @Override
+        public void consumeLine( String line )
+        {
+            events.handleEvent( line );
+        }
     }
 
-    @Override
-    public CommandLineCallable executeCommandLineAsCallable( Commandline cli,
-                                                             StreamConsumer stdOut, StreamConsumer stdErr )
+    private static class CommandReaderAdapter extends InputStream
     {
-        return null;
+        private final AbstractCommandReader commands;
+
+        private byte[] currentBuffer;
+        private int currentPos;
+        private volatile boolean closed;
+
+        CommandReaderAdapter( AbstractCommandReader commands )
+        {
+            this.commands = commands;
+        }
+
+        @Override
+        public int read()
+        {
+            if ( commands.isClosed() )
+            {
+                close();
+            }
+
+            if ( closed )
+            {
+                return -1;
+            }
+
+            if ( currentBuffer == null )
+            {
+                currentBuffer = commands.readNextCommand();
+                if ( currentBuffer == null )
+                {
+                    return -1;
+                }
+            }
+
+            int b =  currentBuffer[currentPos++] & 0xff;
+            if ( currentPos == currentBuffer.length )
+            {
+                currentBuffer = null;
+                currentPos = 0;
+            }
+            return b;
+        }
+
+        @Override
+        public void close()
+        {
+            closed = true;
+        }
     }
 }
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfigurationTest.java
index a8f6c69..451d8a4 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfigurationTest.java
@@ -19,6 +19,7 @@ package org.apache.maven.plugin.surefire.booterclient;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.ExecutableCommandlineFactory;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.plugin.surefire.util.Relocator;
@@ -27,7 +28,6 @@ import org.apache.maven.surefire.booter.Classpath;
 import org.apache.maven.surefire.booter.ClasspathConfiguration;
 import org.apache.maven.surefire.booter.ForkedBooter;
 import org.apache.maven.surefire.booter.StartupConfiguration;
-import org.apache.maven.surefire.booter.SurefireBooterForkException;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -74,6 +74,7 @@ public class DefaultForkConfigurationTest
     private boolean reuseForks;
     private Platform pluginPlatform;
     private ConsoleLogger log;
+    private ExecutableCommandlineFactory executableCommandlineFactory;
 
     @Before
     public void setup()
@@ -90,6 +91,7 @@ public class DefaultForkConfigurationTest
         reuseForks = true;
         pluginPlatform = new Platform();
         log = mock( ConsoleLogger.class );
+        executableCommandlineFactory = mock( ExecutableCommandlineFactory.class );
     }
 
     @Test
@@ -97,16 +99,15 @@ public class DefaultForkConfigurationTest
     {
         DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
                 workingDirectory, modelProperties, argLine, environmentVariables, debug, forkCount, reuseForks,
-                pluginPlatform, log )
+                pluginPlatform, log, executableCommandlineFactory )
         {
 
             @Override
             protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                              @Nonnull String booterThatHasMainMethod,
                                              @Nonnull StartupConfiguration config,
-                                             @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+                                             @Nonnull File dumpLogDirectory )
             {
-
             }
         };
 
@@ -123,16 +124,15 @@ public class DefaultForkConfigurationTest
         argLine = "";
         DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
                 workingDirectory, modelProperties, argLine, environmentVariables, debug, forkCount, reuseForks,
-                pluginPlatform, log )
+                pluginPlatform, log, executableCommandlineFactory )
         {
 
             @Override
             protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                              @Nonnull String booterThatHasMainMethod,
                                              @Nonnull StartupConfiguration config,
-                                             @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+                                             @Nonnull File dumpLogDirectory )
             {
-
             }
         };
 
@@ -149,16 +149,15 @@ public class DefaultForkConfigurationTest
         argLine = "\n\r";
         DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
                 workingDirectory, modelProperties, argLine, environmentVariables, debug, forkCount, reuseForks,
-                pluginPlatform, log )
+                pluginPlatform, log, executableCommandlineFactory )
         {
 
             @Override
             protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                              @Nonnull String booterThatHasMainMethod,
                                              @Nonnull StartupConfiguration config,
-                                             @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+                                             @Nonnull File dumpLogDirectory )
             {
-
             }
         };
 
@@ -175,16 +174,15 @@ public class DefaultForkConfigurationTest
         argLine = "-Dfile.encoding=UTF-8";
         DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
                 workingDirectory, modelProperties, argLine, environmentVariables, debug, forkCount, reuseForks,
-                pluginPlatform, log )
+                pluginPlatform, log, executableCommandlineFactory )
         {
 
             @Override
             protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                              @Nonnull String booterThatHasMainMethod,
                                              @Nonnull StartupConfiguration config,
-                                             @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+                                             @Nonnull File dumpLogDirectory )
             {
-
             }
         };
 
@@ -202,16 +200,15 @@ public class DefaultForkConfigurationTest
         argLine = "-Dfile.encoding=@{encoding}";
         DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
                 workingDirectory, modelProperties, argLine, environmentVariables, debug, forkCount, reuseForks,
-                pluginPlatform, log )
+                pluginPlatform, log, executableCommandlineFactory )
         {
 
             @Override
             protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                              @Nonnull String booterThatHasMainMethod,
                                              @Nonnull StartupConfiguration config,
-                                             @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+                                             @Nonnull File dumpLogDirectory )
             {
-
             }
         };
 
@@ -228,16 +225,15 @@ public class DefaultForkConfigurationTest
         argLine = "a\n\rb";
         DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
                 workingDirectory, modelProperties, argLine, environmentVariables, debug, forkCount, reuseForks,
-                pluginPlatform, log )
+                pluginPlatform, log, executableCommandlineFactory )
         {
 
             @Override
             protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                              @Nonnull String booterThatHasMainMethod,
                                              @Nonnull StartupConfiguration config,
-                                             @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+                                             @Nonnull File dumpLogDirectory )
             {
-
             }
         };
 
@@ -254,16 +250,15 @@ public class DefaultForkConfigurationTest
         argLine = "-Dthread=${surefire.threadNumber}";
         DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
                 workingDirectory, modelProperties, argLine, environmentVariables, debug, forkCount, reuseForks,
-                pluginPlatform, log )
+                pluginPlatform, log, executableCommandlineFactory )
         {
 
             @Override
             protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                              @Nonnull String booterThatHasMainMethod,
                                              @Nonnull StartupConfiguration config,
-                                             @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+                                             @Nonnull File dumpLogDirectory )
             {
-
             }
         };
 
@@ -280,16 +275,15 @@ public class DefaultForkConfigurationTest
         argLine = "-Dthread=${surefire.forkNumber}";
         DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
                 workingDirectory, modelProperties, argLine, environmentVariables, debug, forkCount, reuseForks,
-                pluginPlatform, log )
+                pluginPlatform, log, executableCommandlineFactory )
         {
 
             @Override
             protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                              @Nonnull String booterThatHasMainMethod,
                                              @Nonnull StartupConfiguration config,
-                                             @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+                                             @Nonnull File dumpLogDirectory )
             {
-
             }
         };
 
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfigurationTest.java
index 26410b5..5415e9e 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfigurationTest.java
@@ -66,7 +66,7 @@ public class ModularClasspathForkConfigurationTest
 
         ModularClasspathForkConfiguration config = new ModularClasspathForkConfiguration( booter, tmp, "", pwd,
                 new Properties(), "", new HashMap<String, String>(), true, 1, true, new Platform(),
-                new NullConsoleLogger() )
+                new NullConsoleLogger(), null )
         {
             @Nonnull
             @Override
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 c66321b..be339dd 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
@@ -85,7 +85,7 @@ public final class ForkedBooter
     private ScheduledThreadPoolExecutor jvmTerminator;
     private ProviderConfiguration providerConfiguration;
     private ForkingReporterFactory forkingReporterFactory;
-    private CommandReader commandReader;
+    private volatile CommandReader commandReader;
     private StartupConfiguration startupConfiguration;
     private Object testSet;
 
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkedChannelServer.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkedChannelServer.java
index 970278c..b65dab7 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkedChannelServer.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkedChannelServer.java
@@ -37,7 +37,7 @@ public abstract class ForkedChannelServer
         this.channelConfig = channelConfig;
     }
 
-    protected String getChannelConfig()
+    public String getChannelConfig()
     {
         return channelConfig;
     }