diff --git a/README.md b/README.md
index 7ae794d..a9c2c45 100644
--- a/README.md
+++ b/README.md
@@ -943,6 +943,24 @@ Examples on how and where Gradle's eclipse-plugin could (and should) be improved
`.classpath`-file is affected if the feature is enabled are available on
[GitHub](https://github.com/Alfred-65/gradle-modules-plugin.investigation).
+Preventing "command line too long" errors
+===
+When using many modules, the command line for `--module-path` can become too long.
+A workaround is to use Java's [Command-Line Argument Files](https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111).
+The workaround can be enabled by setting `createCommandLineArgumentFile` to `true` in the `moduleOptions` part in the `run` configuration.
+
+
+Groovy DSL
+
+```groovy
+run {
+ moduleOptions {
+ createCommandLineArgumentFile = true
+ }
+}
+```
+
+
Limitations
===
diff --git a/src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java b/src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java
index 33a733d..dd9f3f7 100644
--- a/src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java
+++ b/src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java
@@ -19,9 +19,9 @@ public class ModuleSystemPlugin implements Plugin {
@Override
public void apply(Project project) {
if(GradleVersion.current().compareTo(GradleVersion.version("5.1")) < 0) {
- LOGGER.warn("WARNING: You use " + GradleVersion.current() +
- ". The minimum version supported (with some limitations) by this plugin is 5.1." +
- " It is strongly recommended to use at least Gradle 5.6.");
+ LOGGER.warn("WARNING: You use {}." +
+ " The minimum version supported (with some limitations) by this plugin is 5.1." +
+ " It is strongly recommended to use at least Gradle 5.6.", GradleVersion.current());
}
project.getPlugins().apply(JavaPlugin.class);
new ModuleName().findModuleName(project).ifPresent(moduleName -> configureModularity(project, moduleName));
diff --git a/src/main/java/org/javamodularity/moduleplugin/extensions/RunModuleOptions.java b/src/main/java/org/javamodularity/moduleplugin/extensions/RunModuleOptions.java
index ce8bb99..0fd90d6 100644
--- a/src/main/java/org/javamodularity/moduleplugin/extensions/RunModuleOptions.java
+++ b/src/main/java/org/javamodularity/moduleplugin/extensions/RunModuleOptions.java
@@ -4,6 +4,16 @@
public class RunModuleOptions extends RuntimeModuleOptions {
+ private Boolean createCommandLineArgumentFile = false;
+
+ public Boolean getCreateCommandLineArgumentFile() {
+ return createCommandLineArgumentFile;
+ }
+
+ public void setCreateCommandLineArgumentFile(Boolean createCommandLineArgumentFile) {
+ this.createCommandLineArgumentFile = createCommandLineArgumentFile;
+ }
+
public RunModuleOptions(Project project) {
super(project);
}
diff --git a/src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java b/src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java
index 613090d..41a39e0 100644
--- a/src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java
+++ b/src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java
@@ -12,30 +12,62 @@
import org.javamodularity.moduleplugin.extensions.RunModuleOptions;
import org.javamodularity.moduleplugin.internal.TaskOption;
+import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
+import java.util.StringJoiner;
import java.util.stream.Collectors;
public class RunTaskMutator extends AbstractExecutionMutator {
private static final Logger LOGGER = Logging.getLogger(RunTaskMutator.class);
+ private static final String LINE_SEP = System.getProperty("line.separator");
public RunTaskMutator(JavaExec execTask, Project project) {
super(execTask, project);
}
public void configureRun() {
- execTask.getExtensions().create("moduleOptions", RunModuleOptions.class, project);
- updateJavaExecTask();
+ RunModuleOptions moduleOptions = execTask.getExtensions().create("moduleOptions", RunModuleOptions.class, project);
+ updateJavaExecTask(moduleOptions);
}
- private void updateJavaExecTask() {
+ private void updateJavaExecTask(RunModuleOptions moduleOptions) {
// don't convert to lambda: https://github.com/java9-modularity/gradle-modules-plugin/issues/54
execTask.doFirst(new Action() {
@Override
public void execute(Task task) {
List jvmArgs = buildJavaExecJvmArgs();
- execTask.setJvmArgs(jvmArgs);
+
+ if (!moduleOptions.getCreateCommandLineArgumentFile()) {
+ execTask.setJvmArgs(jvmArgs);
+ execTask.setClasspath(project.files());
+ }
+
+ // Workaround for 206 command line too long - https://github.com/java9-modularity/gradle-modules-plugin/issues/281
+
+ List newJvmArgs = new ArrayList<>();
+
+ StringJoiner parametersJoiner = new StringJoiner("\"" + LINE_SEP + "\"", "\"", "\"");
+ for (String jvmArg : jvmArgs) {
+ if (jvmArg.startsWith("@")) {
+ newJvmArgs.add(jvmArg);
+ } else {
+ parametersJoiner.add(jvmArg.replace("\\", "\\\\"));
+ }
+ }
+ try {
+ Path parameterFile = Files.createTempFile("jvm-args", ".txt");
+ Files.write(parameterFile, parametersJoiner.toString().getBytes());
+ newJvmArgs.add("@" + parameterFile.toAbsolutePath());
+ execTask.setJvmArgs(newJvmArgs);
+ LOGGER.info("Patched jvmArgs for task {}: {}", execTask.getName(), newJvmArgs);
+ parameterFile.toFile().deleteOnExit();
+ } catch (IOException e) {
+ LOGGER.warn("Could not create temporary file for jvmArgs. Falling back to default behavior.", e);
+ execTask.setJvmArgs(jvmArgs);
+ }
execTask.setClasspath(project.files());
}
});