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()); } });