Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add usage of java Command-Line Argument File on Windows #282

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<details open>
<summary>Groovy DSL</summary>

```groovy
run {
moduleOptions {
createCommandLineArgumentFile = true
}
}
```
</details>


Limitations
===
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public class ModuleSystemPlugin implements Plugin<Project> {
@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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Task>() {
@Override
public void execute(Task task) {
List<String> 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<String> 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());
}
});
Expand Down