diff --git a/pitest-entry/src/main/java/org/pitest/coverage/execute/CoverageProcess.java b/pitest-entry/src/main/java/org/pitest/coverage/execute/CoverageProcess.java
index 22a9d863c..7644446c8 100644
--- a/pitest-entry/src/main/java/org/pitest/coverage/execute/CoverageProcess.java
+++ b/pitest-entry/src/main/java/org/pitest/coverage/execute/CoverageProcess.java
@@ -20,7 +20,7 @@ public class CoverageProcess {
   public CoverageProcess(final ProcessArgs processArgs,
       final CoverageOptions arguments, final ServerSocket socket,
       final List<String> testClasses, final Consumer<CoverageResult> handler) {
-    this.process = new WrappingProcess(socket.getLocalPort(), processArgs,
+    this.process = WrappingProcess.create(socket.getLocalPort(), processArgs,
         CoverageMinion.class);
 
     this.crt = new CommunicationThread(socket, new SendData(arguments, testClasses), new Receive(handler));
diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/execute/MutationTestProcess.java b/pitest-entry/src/main/java/org/pitest/mutationtest/execute/MutationTestProcess.java
index 27b0d50e2..a79667c73 100644
--- a/pitest-entry/src/main/java/org/pitest/mutationtest/execute/MutationTestProcess.java
+++ b/pitest-entry/src/main/java/org/pitest/mutationtest/execute/MutationTestProcess.java
@@ -23,7 +23,7 @@ public class MutationTestProcess {
 
   public MutationTestProcess(final ServerSocket socket,
       final ProcessArgs processArgs, final MinionArguments arguments) {
-    this.process = new WrappingProcess(socket.getLocalPort(), processArgs,
+    this.process = WrappingProcess.create(socket.getLocalPort(), processArgs,
         MutationTestMinion.class);
 
     this.idMap = new ConcurrentHashMap<>();
diff --git a/pitest-entry/src/main/java/org/pitest/process/Java9Process.java b/pitest-entry/src/main/java/org/pitest/process/Java9Process.java
new file mode 100644
index 000000000..51ca17465
--- /dev/null
+++ b/pitest-entry/src/main/java/org/pitest/process/Java9Process.java
@@ -0,0 +1,152 @@
+package org.pitest.process;
+
+import static java.util.Arrays.asList;
+import static org.pitest.functional.prelude.Prelude.or;
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+import org.pitest.functional.FCollection;
+
+/**
+ * Process for java 9+, using file to pass
+ * all parameters
+ */
+public class Java9Process implements WrappingProcess {
+
+    private final int         port;
+    private final ProcessArgs processArgs;
+    private final Class<?>    minionClass;
+    private JavaProcess       process;
+
+    public Java9Process(int port, ProcessArgs args, Class<?> minionClass) {
+        this.port = port;
+        this.processArgs = args;
+        this.minionClass = minionClass;
+    }
+
+    public void start() throws IOException {
+        String[] args = { "" + this.port };
+
+        ProcessBuilder processBuilder = createProcessBuilder(
+                this.processArgs.getJavaExecutable(),
+                this.processArgs.getJvmArgs(),
+                this.minionClass, asList(args),
+                this.processArgs.getJavaAgentFinder(),
+                this.processArgs.getLaunchClassPath());
+
+
+        configureProcessBuilder(processBuilder, this.processArgs.getWorkingDir(),
+                this.processArgs.getEnvironmentVariables());
+
+        Process process = processBuilder.start();
+        this.process = new JavaProcess(process, this.processArgs.getStdout(),
+                this.processArgs.getStdErr());
+    }
+
+    public boolean isAlive() {
+        return process.isAlive();
+    }
+
+    private void configureProcessBuilder(ProcessBuilder processBuilder,
+                                         File workingDirectory, Map<String, String> environmentVariables) {
+        processBuilder.directory(workingDirectory);
+        Map<String, String> environment = processBuilder.environment();
+
+        for (final Map.Entry<String, String> entry : environmentVariables.entrySet()) {
+            environment.put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    public void destroy() {
+        this.process.destroy();
+    }
+
+    private ProcessBuilder createProcessBuilder(String javaProc,
+                                                List<String> args, Class<?> mainClass, List<String> programArgs,
+                                                JavaAgent javaAgent, String classPath) {
+        List<String> cmd = createLaunchArgs(javaAgent, args, mainClass,
+                programArgs, classPath);
+
+        removeJacocoAgent(cmd);
+
+        try {
+            // all arguments are passed via a temporary file, thereby avoiding command line length limits
+            Path argsFile = createArgsFile(cmd);
+            return new ProcessBuilder(asList(javaProc, "@" + argsFile.toFile().getAbsolutePath()));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+    private void removeJacocoAgent(List<String> cmd) {
+        removeFromClassPath(cmd, line -> line.startsWith("-javaagent") && line.contains("jacoco"));
+    }
+
+    private static void removeFromClassPath(List<String> cmd, Predicate<String> match) {
+        for (int i = cmd.size() - 1; i >= 0; i--) {
+            if (match.test(cmd.get(i))) {
+                cmd.remove(i);
+            }
+        }
+    }
+
+    private List<String> createLaunchArgs(JavaAgent agentJarLocator, List<String> args, Class<?> mainClass,
+                                          List<String> programArgs, String classPath) {
+
+        List<String> cmd = new ArrayList<>();
+
+        cmd.add("-classpath");
+        cmd.add(classPath);
+
+        addPITJavaAgent(agentJarLocator, cmd);
+
+        cmd.addAll(args);
+
+        addLaunchJavaAgents(cmd);
+
+        cmd.add(mainClass.getName());
+        cmd.addAll(programArgs);
+        return cmd;
+    }
+
+    private Path createArgsFile(List<String> cmd) throws IOException {
+        Path args = Files.createTempFile("pitest-args", ".args");
+        args.toFile().deleteOnExit();
+        Files.write(args, cmd);
+        return args;
+    }
+
+    private static void addPITJavaAgent(JavaAgent agentJarLocator,
+                                        List<String> cmd) {
+        final Optional<String> jarLocation = agentJarLocator.getJarLocation();
+        jarLocation.ifPresent(l -> cmd.add("-javaagent:" + l));
+    }
+
+    private static void addLaunchJavaAgents(List<String> cmd) {
+        RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
+        List<String> agents = FCollection.filter(rt.getInputArguments(),
+                or(isJavaAgentParam(), isEnvironmentSetting()));
+        cmd.addAll(agents);
+    }
+
+    private static Predicate<String> isEnvironmentSetting() {
+        return a -> a.startsWith("-D");
+    }
+
+    private static Predicate<String> isJavaAgentParam() {
+        return a -> a.toLowerCase().startsWith("-javaagent");
+    }
+
+    public JavaProcess getProcess() {
+        return this.process;
+    }
+}
diff --git a/pitest-entry/src/main/java/org/pitest/process/LegacyProcess.java b/pitest-entry/src/main/java/org/pitest/process/LegacyProcess.java
new file mode 100644
index 000000000..066eca800
--- /dev/null
+++ b/pitest-entry/src/main/java/org/pitest/process/LegacyProcess.java
@@ -0,0 +1,170 @@
+package org.pitest.process;
+
+import static org.pitest.functional.prelude.Prelude.or;
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+import org.pitest.functional.FCollection;
+import org.pitest.util.ManifestUtils;
+
+/**
+ * Process for Java 8, pre module and params file support
+ */
+public class LegacyProcess implements WrappingProcess {
+
+    private final int         port;
+    private final ProcessArgs processArgs;
+    private final Class<?>    minionClass;
+
+    private JavaProcess       process;
+
+    public LegacyProcess(int port, ProcessArgs args, Class<?> minionClass) {
+        this.port = port;
+        this.processArgs = args;
+        this.minionClass = minionClass;
+    }
+
+    public void start() throws IOException {
+        final String[] args = { "" + this.port };
+
+        final ProcessBuilder processBuilder = createProcessBuilder(
+                this.processArgs.getJavaExecutable(),
+                this.processArgs.getJvmArgs(),
+                this.minionClass, Arrays.asList(args),
+                this.processArgs.getJavaAgentFinder(),
+                this.processArgs.getLaunchClassPath());
+
+
+        setClassPathInEnvironment(processBuilder);
+
+        configureProcessBuilder(processBuilder, this.processArgs.getWorkingDir(),
+                this.processArgs.getEnvironmentVariables());
+
+        final Process process = processBuilder.start();
+        this.process = new JavaProcess(process, this.processArgs.getStdout(),
+                this.processArgs.getStdErr());
+    }
+
+    public boolean isAlive() {
+        return process.isAlive();
+    }
+
+
+    // Reportedly passing the classpath as an environment variable rather than on the command
+    // line increases the allowable size of the classpath, but this has not been confirmed
+    private void setClassPathInEnvironment(final ProcessBuilder processBuilder) {
+        if (!processArgs.useClasspathJar()) {
+            processBuilder.environment().put("CLASSPATH", this.processArgs.getLaunchClassPath());
+        }
+    }
+
+    private void configureProcessBuilder(ProcessBuilder processBuilder,
+                                         File workingDirectory, Map<String, String> environmentVariables) {
+        processBuilder.directory(workingDirectory);
+        final Map<String, String> environment = processBuilder.environment();
+
+        for (final Map.Entry<String, String> entry : environmentVariables.entrySet()) {
+            environment.put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    public void destroy() {
+        this.process.destroy();
+    }
+
+    private ProcessBuilder createProcessBuilder(String javaProc,
+                                                List<String> args, Class<?> mainClass, List<String> programArgs,
+                                                JavaAgent javaAgent, String classPath) {
+        final List<String> cmd = createLaunchArgs(javaProc, javaAgent, args, mainClass,
+                programArgs, classPath);
+
+        // IBM jdk adds this, thereby breaking everything
+        removeClassPathProperties(cmd);
+
+        removeJacocoAgent(cmd);
+
+        return new ProcessBuilder(cmd);
+    }
+
+    private void removeJacocoAgent(List<String> cmd) {
+        removeFromClassPath(cmd, line -> line.startsWith("-javaagent") && line.contains("jacoco"));
+    }
+
+    private static void removeClassPathProperties(List<String> cmd) {
+        removeFromClassPath(cmd, s -> s.startsWith("-Djava.class.path"));
+    }
+
+    private static void removeFromClassPath(List<String> cmd, Predicate<String> match) {
+        for (int i = cmd.size() - 1; i >= 0; i--) {
+            if (match.test(cmd.get(i))) {
+                cmd.remove(i);
+            }
+        }
+    }
+
+    private List<String> createLaunchArgs(String javaProcess,
+                                          JavaAgent agentJarLocator, List<String> args, Class<?> mainClass,
+                                          List<String> programArgs, String classPath) {
+
+        final List<String> cmd = new ArrayList<>();
+        cmd.add(javaProcess);
+
+        createClasspathJar(classPath, cmd);
+
+        addPITJavaAgent(agentJarLocator, cmd);
+
+        cmd.addAll(args);
+
+        addLaunchJavaAgents(cmd);
+
+        cmd.add(mainClass.getName());
+        cmd.addAll(programArgs);
+        return cmd;
+    }
+
+    private void createClasspathJar(String classPath, final List<String> cmd) {
+        if (this.processArgs.useClasspathJar()) {
+            try {
+                cmd.add("-classpath");
+                cmd.add(
+                        ManifestUtils.createClasspathJarFile(classPath).getAbsolutePath());
+            } catch (Exception e) {
+                throw new RuntimeException("Unable to create jar to contain classpath",
+                        e);
+            }
+        }
+    }
+
+    private static void addPITJavaAgent(JavaAgent agentJarLocator,
+                                        List<String> cmd) {
+        final Optional<String> jarLocation = agentJarLocator.getJarLocation();
+        jarLocation.ifPresent(l -> cmd.add("-javaagent:" + l));
+    }
+
+    private static void addLaunchJavaAgents(List<String> cmd) {
+        final RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
+        final List<String> agents = FCollection.filter(rt.getInputArguments(),
+                or(isJavaAgentParam(), isEnvironmentSetting()));
+        cmd.addAll(agents);
+    }
+
+    private static Predicate<String> isEnvironmentSetting() {
+        return a -> a.startsWith("-D");
+    }
+
+    private static Predicate<String> isJavaAgentParam() {
+        return a -> a.toLowerCase().startsWith("-javaagent");
+    }
+
+    public JavaProcess getProcess() {
+        return this.process;
+    }
+}
diff --git a/pitest-entry/src/main/java/org/pitest/process/WrappingProcess.java b/pitest-entry/src/main/java/org/pitest/process/WrappingProcess.java
index aa6aca8eb..f0ef3f11b 100644
--- a/pitest-entry/src/main/java/org/pitest/process/WrappingProcess.java
+++ b/pitest-entry/src/main/java/org/pitest/process/WrappingProcess.java
@@ -1,167 +1,24 @@
 package org.pitest.process;
 
-import static org.pitest.functional.prelude.Prelude.or;
-import java.io.File;
 import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Predicate;
 
-import org.pitest.functional.FCollection;
-import org.pitest.util.ManifestUtils;
+public interface WrappingProcess {
 
-public class WrappingProcess {
-
-  private final int         port;
-  private final ProcessArgs processArgs;
-  private final Class<?>    minionClass;
-
-  private JavaProcess       process;
-
-  public WrappingProcess(int port, ProcessArgs args, Class<?> minionClass) {
-    this.port = port;
-    this.processArgs = args;
-    this.minionClass = minionClass;
-  }
-
-  public void start() throws IOException {
-    final String[] args = { "" + this.port };
-
-    final ProcessBuilder processBuilder = createProcessBuilder(
-        this.processArgs.getJavaExecutable(),
-            this.processArgs.getJvmArgs(),
-        this.minionClass, Arrays.asList(args),
-        this.processArgs.getJavaAgentFinder(),
-        this.processArgs.getLaunchClassPath());
-
-    
-    setClassPathInEnvironment(processBuilder);
-        
-    configureProcessBuilder(processBuilder, this.processArgs.getWorkingDir(),
-        this.processArgs.getEnvironmentVariables());
-
-    final Process process = processBuilder.start();
-    this.process = new JavaProcess(process, this.processArgs.getStdout(),
-        this.processArgs.getStdErr());
-  }
-
-  public boolean isAlive() {
-    return process.isAlive();
-  }
-
-  
-   // Reportedly passing the classpath as an environment variable rather than on the command
-   // line increases the allowable size of the classpath, but this has not been confirmed
-  private void setClassPathInEnvironment(final ProcessBuilder processBuilder) {
-    if (!processArgs.useClasspathJar()) {
-      processBuilder.environment().put("CLASSPATH", this.processArgs.getLaunchClassPath());
-    }
-  }
-
-  private void configureProcessBuilder(ProcessBuilder processBuilder,
-      File workingDirectory, Map<String, String> environmentVariables) {
-    processBuilder.directory(workingDirectory);
-    final Map<String, String> environment = processBuilder.environment();
-
-    for (final Map.Entry<String, String> entry : environmentVariables.entrySet()) {
-      environment.put(entry.getKey(), entry.getValue());
-    }
-  }
-
-  public void destroy() {
-    this.process.destroy();
-  }
-
-  private ProcessBuilder createProcessBuilder(String javaProc,
-      List<String> args, Class<?> mainClass, List<String> programArgs,
-      JavaAgent javaAgent, String classPath) {
-    final List<String> cmd = createLaunchArgs(javaProc, javaAgent, args, mainClass,
-        programArgs, classPath);
-
-    // IBM jdk adds this, thereby breaking everything
-    removeClassPathProperties(cmd);
-    
-    removeJacocoAgent(cmd);
-
-    return new ProcessBuilder(cmd);
-  }
-
-  private void removeJacocoAgent(List<String> cmd) {
-    removeFromClassPath(cmd, line -> line.startsWith("-javaagent") && line.contains("jacoco"));
-  }
-
-  private static void removeClassPathProperties(List<String> cmd) {
-    removeFromClassPath(cmd, s -> s.startsWith("-Djava.class.path"));
-  }
-
-  private static void removeFromClassPath(List<String> cmd, Predicate<String> match) {
-    for (int i = cmd.size() - 1; i >= 0; i--) {
-      if (match.test(cmd.get(i))) {
-        cmd.remove(i);
-      }
+  static WrappingProcess create(int port, ProcessArgs args, Class<?> minionClass) {
+    String javaVersion = System.getProperty("java.version");
+    if (javaVersion.startsWith("8") || javaVersion.startsWith("1.8")) {
+      return new LegacyProcess(port, args, minionClass);
     }
-  }
-
-  private List<String> createLaunchArgs(String javaProcess,
-      JavaAgent agentJarLocator, List<String> args, Class<?> mainClass,
-      List<String> programArgs, String classPath) {
-
-    final List<String> cmd = new ArrayList<>();
-    cmd.add(javaProcess);
-
-    createClasspathJar(classPath, cmd);
 
-    addPITJavaAgent(agentJarLocator, cmd);
-
-    cmd.addAll(args);
-
-    addLaunchJavaAgents(cmd);
-
-    cmd.add(mainClass.getName());
-    cmd.addAll(programArgs);
-    return cmd;
+    return new Java9Process(port, args, minionClass);
   }
 
-  private void createClasspathJar(String classPath, final List<String> cmd) {
-    if (this.processArgs.useClasspathJar()) {
-      try {
-        cmd.add("-classpath");
-        cmd.add(
-            ManifestUtils.createClasspathJarFile(classPath).getAbsolutePath());
-      } catch (Exception e) {
-        throw new RuntimeException("Unable to create jar to contain classpath",
-            e);
-      }
-    }
-  }
 
-  private static void addPITJavaAgent(JavaAgent agentJarLocator,
-      List<String> cmd) {
-    final Optional<String> jarLocation = agentJarLocator.getJarLocation();
-    jarLocation.ifPresent(l -> cmd.add("-javaagent:" + l));
-  }
+    void start() throws IOException;
 
-  private static void addLaunchJavaAgents(List<String> cmd) {
-    final RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
-    final List<String> agents = FCollection.filter(rt.getInputArguments(),
-        or(isJavaAgentParam(), isEnvironmentSetting()));
-    cmd.addAll(agents);
-  }
+    boolean isAlive();
 
-  private static Predicate<String> isEnvironmentSetting() {
-    return a -> a.startsWith("-D");
-  }
+    void destroy();
 
-  private static Predicate<String> isJavaAgentParam() {
-    return a -> a.toLowerCase().startsWith("-javaagent");
-  }
-
-  public JavaProcess getProcess() {
-    return this.process;
-  }
+    JavaProcess getProcess();
 }
diff --git a/pitest-entry/src/test/java/org/pitest/process/WrappingProcessTest.java b/pitest-entry/src/test/java/org/pitest/process/WrappingProcessTest.java
index 515889bea..2e43788ed 100644
--- a/pitest-entry/src/test/java/org/pitest/process/WrappingProcessTest.java
+++ b/pitest-entry/src/test/java/org/pitest/process/WrappingProcessTest.java
@@ -42,7 +42,7 @@ public void waitToDieShouldReturnProcessExitCode() throws IOException,
         .andLaunchOptions(launchOptions).andStdout(nullHandler())
         .andStderr(nullHandler());
 
-    final WrappingProcess wrappingProcess = new WrappingProcess(-1, processArgs,
+    final WrappingProcess wrappingProcess = WrappingProcess.create(-1, processArgs,
         getClass());
     wrappingProcess.start();
     final JavaProcess process = wrappingProcess.getProcess();