Skip to content
This repository was archived by the owner on Feb 23, 2023. It is now read-only.

Commit d4e2e74

Browse files
mhalbrittersdeleuze
authored andcommitted
Use argfile when passing arguments to a forked JVM
Closes gh-1567
1 parent 09a9368 commit d4e2e74

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

spring-aot-maven-plugin/src/main/java/org/springframework/aot/maven/AbstractBootstrapMojo.java

+58-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616

1717
package org.springframework.aot.maven;
1818

19+
import java.io.BufferedWriter;
1920
import java.io.File;
2021
import java.io.IOException;
22+
import java.nio.charset.StandardCharsets;
2123
import java.nio.file.Files;
24+
import java.nio.file.Path;
2225
import java.util.List;
2326
import java.util.Map;
2427
import java.util.Optional;
@@ -43,6 +46,7 @@
4346

4447
/**
4548
* @author Brian Clozel
49+
* @uthor Moritz Halbritter
4650
*/
4751
abstract class AbstractBootstrapMojo extends AbstractMojo {
4852

@@ -174,26 +178,78 @@ protected void recreateGeneratedSourcesFolder(File generatedSourcesFolder) throw
174178

175179
protected void forkJvm(File workingDirectory, List<String> args, Map<String, String> environmentVariables)
176180
throws MojoExecutionException {
181+
Path argFile = createArgFile();
177182
try {
183+
writeArgumentsToFile(args, argFile);
178184
RunProcess runProcess = new RunProcess(workingDirectory, getJavaExecutable());
179185
Runtime.getRuntime().addShutdownHook(new Thread(new RunProcessKiller(runProcess)));
180-
int exitCode = runProcess.run(true, args, environmentVariables);
186+
int exitCode = runProcess.run(true, List.of("@" + argFile), environmentVariables);
181187
if (exitCode == 0 || exitCode == 130) {
182188
return;
183189
}
184190
throw new MojoExecutionException("Bootstrap code generator finished with exit code: " + exitCode);
185191
}
186192
catch (Exception ex) {
193+
if (getLog().isDebugEnabled()) {
194+
getLog().debug("Content of arg file:");
195+
getLog().debug(readContent(argFile));
196+
}
187197
throw new MojoExecutionException("Could not exec java", ex);
188198
}
199+
finally {
200+
deleteFile(argFile);
201+
}
202+
}
203+
204+
private String readContent(Path file) {
205+
if (!Files.exists(file)) {
206+
return "<file doesn't exist>";
207+
}
208+
try {
209+
return Files.readString(file);
210+
}
211+
catch (IOException e) {
212+
return "<exception while reading file: " + e.getMessage() + ">";
213+
}
214+
}
215+
216+
private void writeArgumentsToFile(List<String> args, Path argFile) throws IOException {
217+
// See https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-4856361B-8BFD-4964-AE84-121F5F6CF111
218+
try (BufferedWriter writer = Files.newBufferedWriter(argFile, StandardCharsets.UTF_8)) {
219+
for (String arg : args) {
220+
String escaped = arg.replace("\\", "\\\\");
221+
writer.write('"');
222+
writer.write(escaped);
223+
writer.write('"');
224+
writer.newLine();
225+
}
226+
}
227+
}
228+
229+
private void deleteFile(Path file) {
230+
try {
231+
Files.deleteIfExists(file);
232+
}
233+
catch (IOException ex) {
234+
getLog().debug("Failed to delete file " + file, ex);
235+
}
236+
}
237+
238+
private Path createArgFile() throws MojoExecutionException {
239+
try {
240+
return Files.createTempFile("spring-aot-maven-plugin", ".arg").toAbsolutePath();
241+
}
242+
catch (IOException ex) {
243+
throw new MojoExecutionException("Failed to generate arg file", ex);
244+
}
189245
}
190246

191247
protected String getJavaExecutable() {
192248
Toolchain toolchain = this.toolchainManager.getToolchainFromBuildContext("jdk", this.session);
193249
String javaExecutable = (toolchain != null) ? toolchain.findTool("java") : null;
194250
return (javaExecutable != null) ? javaExecutable : new JavaExecutable().toString();
195251
}
196-
252+
197253
protected static final class RunProcessKiller implements Runnable {
198254

199255
private final RunProcess runProcess;

0 commit comments

Comments
 (0)