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 2020/04/13 19:30:55 UTC

[maven-surefire] branch maven2surefire-jvm-communication updated: keeping backwards compatibility - printing corrupted stream

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 c5757cc  keeping backwards compatibility - printing corrupted stream
c5757cc is described below

commit c5757cc1f2103dd3101b8606d261795f8b6226cd
Author: tibordigana <ti...@apache.org>
AuthorDate: Mon Apr 13 21:30:48 2020 +0200

    keeping backwards compatibility - printing corrupted stream
---
 .../plugin/surefire/booterclient/ForkStarter.java  |  51 ++++++++-
 .../surefire/extensions/EventConsumerThread.java   |  35 +++++-
 .../surefire/extensions/LegacyForkChannel.java     |  18 ++-
 .../surefire/extensions/LegacyForkNodeFactory.java |   7 +-
 .../surefire/extensions/SurefireForkChannel.java   |  15 ++-
 .../extensions/SurefireForkNodeFactory.java        |   8 +-
 .../booterclient/ForkingRunListenerTest.java       |   6 +-
 .../booterclient/output/ForkClientTest.java        |  25 ++++-
 .../maven/plugin/surefire/extensions/E2ETest.java  |   7 +-
 .../extensions/ForkedProcessEventNotifierTest.java | 125 ++++++++++++++++-----
 .../maven/surefire/extensions/ForkChannelTest.java |  34 +++++-
 .../maven/surefire/extensions/ForkChannel.java     |  21 ++--
 ...ForkNodeFactory.java => ForkNodeArguments.java} |  24 ++--
 .../maven/surefire/extensions/ForkNodeFactory.java |   9 +-
 14 files changed, 289 insertions(+), 96 deletions(-)

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 b27dacb..44c9f99 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
@@ -45,6 +45,7 @@ import org.apache.maven.surefire.extensions.CloseableDaemonThread;
 import org.apache.maven.surefire.extensions.EventHandler;
 import org.apache.maven.surefire.extensions.ForkChannel;
 import org.apache.maven.surefire.extensions.ForkNodeFactory;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.util.CommandlineExecutor;
 import org.apache.maven.surefire.extensions.util.CommandlineStreams;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
@@ -63,9 +64,11 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Queue;
+import java.util.Set;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentSkipListSet;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
@@ -131,6 +134,8 @@ public class ForkStarter
 
     private static final AtomicInteger SYSTEM_PROPERTIES_FILE_COUNTER = new AtomicInteger();
 
+    private final Set<String> logsAtEnd = new ConcurrentSkipListSet<>();
+
     private final ScheduledExecutorService pingThreadScheduler = createPingScheduler();
 
     private final ScheduledExecutorService timeoutCheckScheduler;
@@ -266,6 +271,10 @@ public class ForkStarter
             defaultReporterFactory.close();
             pingThreadScheduler.shutdownNow();
             timeoutCheckScheduler.shutdownNow();
+            for ( String line : logsAtEnd )
+            {
+                log.warning( line );
+            }
         }
     }
 
@@ -561,9 +570,10 @@ public class ForkStarter
         final File surefireProperties;
         final File systPropsFile;
         final ForkChannel forkChannel;
+        File dumpLogDir = replaceForkThreadsInPath( startupReportConfiguration.getReportsDirectory(), forkNumber );
         try
         {
-            forkChannel = forkNodeFactory.createForkChannel( forkNumber, log );
+            forkChannel = forkNodeFactory.createForkChannel( new ForkedNodeArg( forkNumber, dumpLogDir ) );
             closer.addCloseable( forkChannel );
             tempDir = forkConfiguration.getTempDirectory().getCanonicalPath();
             BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration );
@@ -594,7 +604,6 @@ public class ForkStarter
             throw new SurefireBooterForkException( "Error creating properties files for forking", e );
         }
 
-        File dumpLogDir = replaceForkThreadsInPath( startupReportConfiguration.getReportsDirectory(), forkNumber );
         OutputStreamFlushableCommandline cli =
                 forkConfiguration.createCommandLine( startupConfiguration, forkNumber, dumpLogDir );
 
@@ -867,4 +876,42 @@ public class ForkStarter
             }
         }, 0, TIMEOUT_CHECK_PERIOD_MILLIS, MILLISECONDS );
     }
+
+    private final class ForkedNodeArg implements ForkNodeArguments
+    {
+        private final int forkChannelId;
+        private final File dumpLogDir;
+
+        ForkedNodeArg( int forkChannelId, File dumpLogDir )
+        {
+            this.forkChannelId = forkChannelId;
+            this.dumpLogDir = dumpLogDir;
+        }
+
+        @Override
+        public int getForkChannelId()
+        {
+            return forkChannelId;
+        }
+
+        @Override
+        @Nonnull
+        public File dumpStreamText( @Nonnull String text )
+        {
+            return InPluginProcessDumpSingleton.getSingleton().dumpStreamText( text, dumpLogDir, forkChannelId );
+        }
+
+        @Override
+        public void logWarningAtEnd( @Nonnull String text )
+        {
+            logsAtEnd.add( text );
+        }
+
+        @Nonnull
+        @Override
+        public ConsoleLogger getConsoleLogger()
+        {
+            return log;
+        }
+    }
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
index 8b8e2f3..35fef0e 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
@@ -46,6 +46,7 @@ import org.apache.maven.surefire.eventapi.TestsetCompletedEvent;
 import org.apache.maven.surefire.eventapi.TestsetStartingEvent;
 import org.apache.maven.surefire.extensions.CloseableDaemonThread;
 import org.apache.maven.surefire.extensions.EventHandler;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 import org.apache.maven.surefire.report.RunMode;
 import org.apache.maven.surefire.report.StackTraceWriter;
@@ -53,6 +54,7 @@ import org.apache.maven.surefire.report.TestSetReportEntry;
 import org.apache.maven.surefire.shared.codec.binary.Base64;
 
 import javax.annotation.Nonnull;
+import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ReadableByteChannel;
@@ -78,20 +80,20 @@ public class EventConsumerThread extends CloseableDaemonThread
     private final ReadableByteChannel channel;
     private final EventHandler<Event> eventHandler;
     private final CountdownCloseable countdownCloseable;
-    private final ConsoleLogger logger;
+    private final ForkNodeArguments arguments;
     private volatile boolean disabled;
 
     public EventConsumerThread( @Nonnull String threadName,
                                 @Nonnull ReadableByteChannel channel,
                                 @Nonnull EventHandler<Event> eventHandler,
                                 @Nonnull CountdownCloseable countdownCloseable,
-                                @Nonnull ConsoleLogger logger )
+                                @Nonnull ForkNodeArguments arguments )
     {
         super( threadName );
         this.channel = channel;
         this.eventHandler = eventHandler;
         this.countdownCloseable = countdownCloseable;
-        this.logger = logger;
+        this.arguments = arguments;
     }
 
     @Override
@@ -220,14 +222,35 @@ public class EventConsumerThread extends CloseableDaemonThread
     {
         if ( line.length() != 0 )
         {
-            String s = line.toString();
+            ConsoleLogger logger = arguments.getConsoleLogger();
+            String s = line.toString().trim();
             if ( s.contains( PRINTABLE_JVM_NATIVE_STREAM ) )
             {
-                logger.info( s );
+                if ( logger.isDebugEnabled() )
+                {
+                    logger.debug( s );
+                }
+                else if ( logger.isInfoEnabled() )
+                {
+                    logger.info( s );
+                }
+                else
+                {
+                    // In case of debugging forked JVM, see PRINTABLE_JVM_NATIVE_STREAM.
+                    System.out.println( s );
+                }
             }
             else
             {
-                logger.error( s );
+                String msg = "Corrupted STDOUT by directly writing to native stream in forked JVM "
+                    + arguments.getForkChannelId() + ".";
+                File dumpFile = arguments.dumpStreamText( msg + " Stream '" + s + "'." );
+                arguments.logWarningAtEnd( msg + " See FAQ web page and the dump file " + dumpFile.getAbsolutePath() );
+
+                if ( logger.isDebugEnabled() )
+                {
+                    logger.debug( s );
+                }
             }
         }
     }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java
index d490693..e13846b 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java
@@ -19,12 +19,12 @@ package org.apache.maven.plugin.surefire.extensions;
  * under the License.
  */
 
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.eventapi.Event;
 import org.apache.maven.surefire.extensions.CloseableDaemonThread;
 import org.apache.maven.surefire.extensions.CommandReader;
 import org.apache.maven.surefire.extensions.EventHandler;
 import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 
 import javax.annotation.Nonnull;
@@ -41,12 +41,9 @@ import java.nio.channels.WritableByteChannel;
  */
 final class LegacyForkChannel extends ForkChannel
 {
-    private final ConsoleLogger logger;
-
-    protected LegacyForkChannel( int forkChannelId, ConsoleLogger logger )
+    LegacyForkChannel( @Nonnull ForkNodeArguments arguments )
     {
-        super( forkChannelId );
-        this.logger = logger;
+        super( arguments );
     }
 
     @Override
@@ -57,7 +54,7 @@ final class LegacyForkChannel extends ForkChannel
     @Override
     public String getForkNodeConnectionString()
     {
-        return "pipe://" + getForkChannelId();
+        return "pipe://" + getArguments().getForkChannelId();
     }
 
     @Override
@@ -70,7 +67,8 @@ final class LegacyForkChannel extends ForkChannel
     public CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands,
                                                     WritableByteChannel stdIn )
     {
-        return new StreamFeeder( "std-in-fork-" + getForkChannelId(), stdIn, commands, logger );
+        return new StreamFeeder( "std-in-fork-" + getArguments().getForkChannelId(), stdIn, commands,
+            getArguments().getConsoleLogger() );
     }
 
     @Override
@@ -78,8 +76,8 @@ final class LegacyForkChannel extends ForkChannel
                                                    @Nonnull CountdownCloseable countdownCloseable,
                                                    ReadableByteChannel stdOut )
     {
-        return new EventConsumerThread( "fork-" + getForkChannelId() + "-event-thread", stdOut,
-            eventHandler, countdownCloseable, logger );
+        return new EventConsumerThread( "fork-" + getArguments().getForkChannelId() + "-event-thread", stdOut,
+            eventHandler, countdownCloseable, getArguments() );
     }
 
     @Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
index ca2010b..29d79af 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
@@ -19,11 +19,10 @@ package org.apache.maven.plugin.surefire.extensions;
  * under the License.
  */
 
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.ForkNodeFactory;
 
-import javax.annotation.Nonnegative;
 import javax.annotation.Nonnull;
 
 /**
@@ -33,8 +32,8 @@ public class LegacyForkNodeFactory implements ForkNodeFactory
 {
     @Nonnull
     @Override
-    public ForkChannel createForkChannel( @Nonnegative int forkChannelId, ConsoleLogger logger )
+    public ForkChannel createForkChannel( @Nonnull ForkNodeArguments arguments )
     {
-        return new LegacyForkChannel( forkChannelId, logger );
+        return new LegacyForkChannel( arguments );
     }
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java
index e741a68..11aeb18 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java
@@ -19,12 +19,12 @@ package org.apache.maven.plugin.surefire.extensions;
  * under the License.
  */
 
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.eventapi.Event;
 import org.apache.maven.surefire.extensions.CloseableDaemonThread;
 import org.apache.maven.surefire.extensions.CommandReader;
 import org.apache.maven.surefire.extensions.EventHandler;
 import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 
 import javax.annotation.Nonnull;
@@ -71,16 +71,14 @@ final class SurefireForkChannel extends ForkChannel
 {
     private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool( newDaemonThreadFactory() );
 
-    private final ConsoleLogger logger;
     private final AsynchronousServerSocketChannel server;
     private final String localHost;
     private final int localPort;
     private volatile AsynchronousSocketChannel worker;
 
-    SurefireForkChannel( int forkChannelId, @Nonnull ConsoleLogger logger ) throws IOException
+    SurefireForkChannel( @Nonnull ForkNodeArguments arguments ) throws IOException
     {
-        super( forkChannelId );
-        this.logger = logger;
+        super( arguments );
         server = open( withThreadPool( THREAD_POOL ) );
         setTrueOptions( SO_REUSEADDR, TCP_NODELAY, SO_KEEPALIVE );
         InetAddress ip = Inet4Address.getLoopbackAddress();
@@ -145,7 +143,8 @@ final class SurefireForkChannel extends ForkChannel
         // only newChannel flushes the message
         // newBufferedChannel does not flush
         WritableByteChannel channel = newChannel( newOutputStream( worker ) );
-        return new StreamFeeder( "commands-fork-" + getForkChannelId(), channel, commands, logger );
+        return new StreamFeeder( "commands-fork-" + getArguments().getForkChannelId(), channel, commands,
+            getArguments().getConsoleLogger() );
     }
 
     @Override
@@ -154,8 +153,8 @@ final class SurefireForkChannel extends ForkChannel
                                                    ReadableByteChannel stdOut )
     {
         ReadableByteChannel channel = newBufferedChannel( newInputStream( worker ) );
-        return new EventConsumerThread( "fork-" + getForkChannelId() + "-event-thread", channel,
-            eventHandler, countdownCloseable, logger );
+        return new EventConsumerThread( "fork-" + getArguments().getForkChannelId() + "-event-thread", channel,
+            eventHandler, countdownCloseable, getArguments() );
     }
 
     @Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
index 1c4aabc..0b47784 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
@@ -19,11 +19,10 @@ package org.apache.maven.plugin.surefire.extensions;
  * under the License.
  */
 
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.ForkNodeFactory;
 
-import javax.annotation.Nonnegative;
 import javax.annotation.Nonnull;
 import java.io.IOException;
 
@@ -34,8 +33,9 @@ public class SurefireForkNodeFactory implements ForkNodeFactory
 {
     @Nonnull
     @Override
-    public ForkChannel createForkChannel( @Nonnegative int forkChannelId, ConsoleLogger logger ) throws IOException
+    public ForkChannel createForkChannel( @Nonnull ForkNodeArguments arguments )
+        throws IOException
     {
-        return new SurefireForkChannel( forkChannelId, logger );
+        return new SurefireForkChannel( arguments );
     }
 }
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
index 8aeba39..4c1ac37 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
@@ -28,6 +28,7 @@ import org.apache.maven.surefire.booter.ForkingRunListener;
 import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
 import org.apache.maven.surefire.eventapi.Event;
 import org.apache.maven.surefire.extensions.EventHandler;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 import org.apache.maven.surefire.report.CategorizedReportEntry;
 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
@@ -57,6 +58,7 @@ import java.util.concurrent.TimeUnit;
 import static org.apache.maven.surefire.util.internal.Channels.newBufferedChannel;
 import static org.apache.maven.surefire.util.internal.Channels.newChannel;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 /**
  * @author Kristian Rosenvold
@@ -283,8 +285,10 @@ public class ForkingRunListenerTest
         EH handler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
         ConsoleLogger logger = mock( ConsoleLogger.class );
+        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+        when( arguments.getConsoleLogger() ).thenReturn( logger );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( stream ) );
-        try ( EventConsumerThread t = new EventConsumerThread( "t", channel, handler, countdown, logger ) )
+        try ( EventConsumerThread t = new EventConsumerThread( "t", channel, handler, countdown, arguments ) )
         {
             t.start();
             countdown.awaitClosed();
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
index 453e735..67342e3 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
@@ -47,6 +47,7 @@ import org.apache.maven.surefire.eventapi.TestSucceededEvent;
 import org.apache.maven.surefire.eventapi.TestsetCompletedEvent;
 import org.apache.maven.surefire.eventapi.TestsetStartingEvent;
 import org.apache.maven.surefire.extensions.EventHandler;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 import org.apache.maven.surefire.report.ReportEntry;
 import org.apache.maven.surefire.report.SafeThrowable;
@@ -125,8 +126,12 @@ public class ForkClientTest
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
         ConsoleLogger logger = mock( ConsoleLogger.class );
+        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        when( logger.isDebugEnabled() ).thenReturn( false );
+        when( logger.isInfoEnabled() ).thenReturn( true );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
-        try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+        try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
 
@@ -139,6 +144,10 @@ public class ForkClientTest
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
 
+        verify( logger ).isDebugEnabled();
+
+        verify( logger ).isInfoEnabled();
+
         verifyNoMoreInteractions( logger );
     }
 
@@ -153,8 +162,12 @@ public class ForkClientTest
             .thenReturn( false );
         when( logger.isInfoEnabled() )
             .thenReturn( true );
+        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        when( logger.isDebugEnabled() ).thenReturn( true );
+        when( logger.isInfoEnabled() ).thenReturn( false );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
-        try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+        try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
 
@@ -165,7 +178,7 @@ public class ForkClientTest
                 .isEqualTo( BOOTERCODE_BYE );
 
             verify( logger )
-                .info( "Listening for transport dt_socket at address: bla" );
+                .debug( "Listening for transport dt_socket at address: bla" );
 
             countdown.awaitClosed();
         }
@@ -173,6 +186,8 @@ public class ForkClientTest
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
 
+        verify( logger ).isDebugEnabled();
+
         verifyNoMoreInteractions( logger );
     }
 
@@ -518,8 +533,10 @@ public class ForkClientTest
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
         ConsoleLogger logger = mock( ConsoleLogger.class );
+        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+        when( arguments.getConsoleLogger() ).thenReturn( logger );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
-        try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+        try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
 
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/E2ETest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/E2ETest.java
index 8f4fe5d..80a3474 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/E2ETest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/E2ETest.java
@@ -24,6 +24,7 @@ import org.apache.maven.surefire.booter.MasterProcessChannelEncoder;
 import org.apache.maven.surefire.booter.spi.SurefireMasterProcessChannelProcessorFactory;
 import org.apache.maven.surefire.eventapi.Event;
 import org.apache.maven.surefire.extensions.EventHandler;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
 import org.junit.Test;
@@ -37,6 +38,7 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 /**
  * Simulates the End To End use case where Maven process and Surefire process communicate using the TCP/IP protocol.
@@ -51,7 +53,10 @@ public class E2ETest
     public void test() throws Exception
     {
         ConsoleLogger logger = mock( ConsoleLogger.class );
-        final SurefireForkChannel server = new SurefireForkChannel( 1, logger );
+        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+        when( arguments.getForkChannelId() ).thenReturn( 1 );
+        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        final SurefireForkChannel server = new SurefireForkChannel( arguments );
 
         final String connection = server.getForkNodeConnectionString();
 
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/ForkedProcessEventNotifierTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/ForkedProcessEventNotifierTest.java
index 369abe5..4078de0 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/ForkedProcessEventNotifierTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/ForkedProcessEventNotifierTest.java
@@ -33,6 +33,7 @@ import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerUtils;
 import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
 import org.apache.maven.surefire.eventapi.Event;
 import org.apache.maven.surefire.extensions.EventHandler;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 import org.apache.maven.surefire.report.ReportEntry;
 import org.apache.maven.surefire.report.RunMode;
@@ -49,6 +50,7 @@ import org.junit.experimental.theories.Theories;
 import org.junit.experimental.theories.Theory;
 import org.junit.rules.ExpectedException;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.powermock.core.classloader.annotations.PowerMockIgnore;
 import org.powermock.modules.junit4.PowerMockRunner;
 
@@ -56,6 +58,7 @@ import javax.annotation.Nonnull;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
+import java.io.File;
 import java.io.LineNumberReader;
 import java.io.PrintStream;
 import java.io.StringReader;
@@ -69,16 +72,18 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import static org.apache.maven.surefire.util.internal.Channels.newBufferedChannel;
-import static org.apache.maven.surefire.util.internal.Channels.newChannel;
+import static java.lang.String.format;
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.Arrays.copyOfRange;
-import static org.apache.maven.surefire.shared.codec.binary.Base64.encodeBase64String;
 import static org.apache.maven.surefire.report.RunMode.NORMAL_RUN;
+import static org.apache.maven.surefire.shared.codec.binary.Base64.encodeBase64String;
+import static org.apache.maven.surefire.util.internal.Channels.newBufferedChannel;
+import static org.apache.maven.surefire.util.internal.Channels.newChannel;
 import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Index.atIndex;
 import static org.junit.Assert.assertTrue;
 import static org.junit.rules.ExpectedException.none;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -131,7 +136,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 for ( int i = 0; i < props.size(); i++ )
@@ -334,7 +341,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -371,7 +380,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -420,7 +431,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -451,7 +464,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -478,7 +493,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -505,7 +522,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -534,7 +553,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -563,7 +584,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -591,7 +614,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -622,7 +647,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -651,7 +678,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -680,7 +709,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -709,7 +740,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -738,7 +771,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -767,7 +802,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -796,7 +833,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -824,7 +863,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -853,14 +894,40 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            when( logger.isDebugEnabled() ).thenReturn( true );
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 countdown.awaitClosed();
             }
 
-            verify( logger, times( 1 ) )
-                .error( eq( ":maven-surefire-event:abnormal-run:" ) );
+            ArgumentCaptor<String> dumpLine = ArgumentCaptor.forClass( String.class );
+            verify( logger, times( 2 ) ).debug( dumpLine.capture() );
+            assertThat( dumpLine.getAllValues() )
+                .hasSize( 2 )
+                .contains( ":maven-surefire-event:abnormal-run:", atIndex( 0 ) )
+                .contains( "-:", atIndex( 1 ) );
+
+            ArgumentCaptor<String> dumpText = ArgumentCaptor.forClass( String.class );
+            verify( arguments, times( 2 ) ).dumpStreamText( dumpText.capture() );
+            String dump = "Corrupted STDOUT by directly writing to native stream in forked JVM 0.";
+            assertThat( dumpText.getAllValues() )
+                .hasSize( 2 )
+                .contains( format( dump + " Stream '%s'.", ":maven-surefire-event:abnormal-run:" ), atIndex( 0 ) )
+                .contains( format( dump + " Stream '%s'.", "-:" ), atIndex( 1 ) );
+
+            ArgumentCaptor<String> warning = ArgumentCaptor.forClass( String.class );
+            verify( arguments, times( 2 ) ).logWarningAtEnd( warning.capture() );
+            dump += " See FAQ web page and the dump file ";
+            assertThat( warning.getAllValues() )
+                .hasSize( 2 );
+            assertThat( warning.getAllValues().get( 0 ) )
+                .startsWith( dump );
+            assertThat( warning.getAllValues().get( 1 ) )
+                .startsWith( dump );
         }
 
         @Test
@@ -886,7 +953,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
@@ -995,7 +1064,9 @@ public class ForkedProcessEventNotifierTest
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
             ConsoleLogger logger = mock( ConsoleLogger.class );
-            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, logger ) )
+            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
+            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/surefire/extensions/ForkChannelTest.java b/maven-surefire-common/src/test/java/org/apache/maven/surefire/extensions/ForkChannelTest.java
index c3f6a8c..7b20825 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/surefire/extensions/ForkChannelTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/surefire/extensions/ForkChannelTest.java
@@ -23,6 +23,7 @@ import org.apache.maven.plugin.surefire.booterclient.MockReporter;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream;
 import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream.TestLessInputStreamBuilder;
 import org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory;
+import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.eventapi.ControlByeEvent;
 import org.apache.maven.surefire.eventapi.Event;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
@@ -30,6 +31,7 @@ import org.junit.Test;
 
 import javax.annotation.Nonnull;
 import java.io.Closeable;
+import java.io.File;
 import java.io.IOException;
 import java.net.Socket;
 import java.net.URI;
@@ -54,10 +56,38 @@ public class ForkChannelTest
     @Test( timeout = TESTCASE_TIMEOUT )
     public void shouldRequestReplyMessagesViaTCP() throws Exception
     {
+        ForkNodeArguments forkNodeArguments = new ForkNodeArguments()
+        {
+            @Override
+            public int getForkChannelId()
+            {
+                return 1;
+            }
+
+            @Override
+            @Nonnull
+            public File dumpStreamText( @Nonnull String text )
+            {
+                return new File( "" );
+            }
+
+            @Override
+            public void logWarningAtEnd( @Nonnull String text )
+            {
+            }
+
+            @Override
+            @Nonnull
+            public ConsoleLogger getConsoleLogger()
+            {
+                return new MockReporter();
+            }
+        };
+
         ForkNodeFactory factory = new SurefireForkNodeFactory();
-        try ( ForkChannel channel = factory.createForkChannel( 1, new MockReporter() ) )
+        try ( ForkChannel channel = factory.createForkChannel( forkNodeArguments ) )
         {
-            assertThat( channel.getForkChannelId() )
+            assertThat( channel.getArguments().getForkChannelId() )
                 .isEqualTo( 1 );
 
             assertThat( channel.useStdOut() )
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java
index ea6b0b9..dac54f2 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java
@@ -30,7 +30,7 @@ import java.nio.channels.WritableByteChannel;
 
 /**
  * It's a session object used only by a particular Thread in ForkStarter
- * and dedicated forked JVM {@link #getForkChannelId()}. It represents a server.
+ * and dedicated forked JVM. It represents a server.
  * <br>
  * <br>
  * It connects with a client {@link #connectToClient()}, provides a connection string
@@ -41,14 +41,15 @@ import java.nio.channels.WritableByteChannel;
  */
 public abstract class ForkChannel implements Closeable
 {
-    private final int forkChannelId;
+    @Nonnull
+    private final ForkNodeArguments arguments;
 
     /**
-     * @param forkChannelId the index of the forked JVM, from 1 to N.
+     * @param arguments data necessary for command reader and event handler.
      */
-    protected ForkChannel( int forkChannelId )
+    protected ForkChannel( @Nonnull ForkNodeArguments arguments )
     {
-        this.forkChannelId = forkChannelId;
+        this.arguments = arguments;
     }
 
     public abstract void connectToClient() throws IOException;
@@ -96,13 +97,9 @@ public abstract class ForkChannel implements Closeable
                                                             ReadableByteChannel stdOut )
         throws IOException;
 
-    /**
-     * The index of the fork.
-     *
-     * @return the index of the forked JVM, from 1 to N.
-     */
-    protected final int getForkChannelId()
+    @Nonnull
+    protected ForkNodeArguments getArguments()
     {
-        return forkChannelId;
+        return arguments;
     }
 }
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeArguments.java
similarity index 69%
copy from surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
copy to surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeArguments.java
index 5161261..bdd0b2e 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeArguments.java
@@ -23,23 +23,29 @@ import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 
 import javax.annotation.Nonnegative;
 import javax.annotation.Nonnull;
-import java.io.IOException;
+import java.io.File;
 
 /**
- * This is the plugin extension as a factory of {@link ForkChannel}.
+ * The properties related to the current JVM.
  *
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
  * @since 3.0.0-M5
  */
-public interface ForkNodeFactory
+public interface ForkNodeArguments
 {
     /**
-     * Opens and closes the channel.
+     * The index of the forked JVM, from 1 to N.
      *
-     * @param forkChannelId the ID of forked JVM
-     * @param logger the console logger
-     * @return specific implementation of the communication channel
-     * @throws IOException if cannot open the channel
+     * @return index of the forked JVM
      */
-    @Nonnull ForkChannel createForkChannel( @Nonnegative int forkChannelId, ConsoleLogger logger ) throws IOException;
+    @Nonnegative
+    int getForkChannelId();
+
+    @Nonnull
+    File dumpStreamText( @Nonnull String text );
+
+    void logWarningAtEnd( @Nonnull String text );
+
+    @Nonnull
+    ConsoleLogger getConsoleLogger();
 }
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
index 5161261..b5fe150 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
@@ -19,9 +19,6 @@ package org.apache.maven.surefire.extensions;
  * under the License.
  */
 
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
-
-import javax.annotation.Nonnegative;
 import javax.annotation.Nonnull;
 import java.io.IOException;
 
@@ -36,10 +33,10 @@ public interface ForkNodeFactory
     /**
      * Opens and closes the channel.
      *
-     * @param forkChannelId the ID of forked JVM
-     * @param logger the console logger
+     * @param arguments fork starter properties
      * @return specific implementation of the communication channel
      * @throws IOException if cannot open the channel
      */
-    @Nonnull ForkChannel createForkChannel( @Nonnegative int forkChannelId, ConsoleLogger logger ) throws IOException;
+    @Nonnull
+    ForkChannel createForkChannel( @Nonnull ForkNodeArguments arguments ) throws IOException;
 }