Skip to content

Commit c560538

Browse files
committed
Use @QuarkusIntegrationTest tests as a test run for AOT file generation
This uses the process outlined by https://openjdk.org/jeps/514 to generate a file named `app.aot` inside the `quarkus-app` directory (i.e. next to the jar) when `-Dquarkus.package.jar.appcds.enabled=true` has been set
1 parent 7e995eb commit c560538

File tree

4 files changed

+32
-24
lines changed

4 files changed

+32
-24
lines changed

test-framework/common/src/main/java/io/quarkus/test/common/DefaultJarLauncher.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class DefaultJarLauncher implements JarArtifactLauncher {
5050
private List<String> argLine;
5151
private Map<String, String> env;
5252
private Path jarPath;
53+
private boolean generateAotFile;
5354

5455
private final Map<String, String> systemProps = new HashMap<>();
5556
private Process quarkusProcess;
@@ -65,6 +66,7 @@ public void init(JarArtifactLauncher.JarInitContext initContext) {
6566
this.argLine = initContext.argLine();
6667
this.env = initContext.env();
6768
this.jarPath = initContext.jarPath();
69+
this.generateAotFile = initContext.generateAotFile();
6870
}
6971

7072
public void start() throws IOException {
@@ -112,6 +114,9 @@ public void start(String[] programArgs, boolean handleIo) throws IOException {
112114
if (!argLine.isEmpty()) {
113115
args.addAll(argLine);
114116
}
117+
if (generateAotFile) {
118+
args.add("-XX:AOTCacheOutput=%s".formatted(jarPath.resolveSibling("app.aot")));
119+
}
115120
if (HTTP_PRESENT) {
116121
args.add("-Dquarkus.http.port=" + httpPort);
117122
args.add("-Dquarkus.http.ssl-port=" + httpsPort);

test-framework/common/src/main/java/io/quarkus/test/common/JarArtifactLauncher.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ public interface JarArtifactLauncher extends ArtifactLauncher<JarArtifactLaunche
1111
interface JarInitContext extends InitContext {
1212

1313
Path jarPath();
14+
15+
boolean generateAotFile();
1416
}
1517
}

test-framework/common/src/main/java/io/quarkus/test/common/LauncherUtil.java

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import java.nio.file.Path;
1010
import java.time.Duration;
1111
import java.util.ArrayList;
12-
import java.util.HashMap;
1312
import java.util.List;
1413
import java.util.Map;
1514
import java.util.ServiceLoader;
@@ -46,32 +45,24 @@ public static Config installAndGetSomeConfig() {
4645
* as can be seen in <a href="https://github.com/quarkusio/quarkus/issues/33229">here</a>
4746
*/
4847
static Process launchProcessAndDrainIO(List<String> args, Map<String, String> env) throws IOException {
49-
Process process = launchProcess(args, env);
50-
new Thread(new ProcessReader(process.getInputStream())).start();
51-
new Thread(new ProcessReader(process.getErrorStream())).start();
48+
ProcessBuilder pb = new ProcessBuilder(args)
49+
.redirectOutput(ProcessBuilder.Redirect.DISCARD)
50+
.redirectError(ProcessBuilder.Redirect.DISCARD)
51+
.redirectInput(ProcessBuilder.Redirect.INHERIT);
52+
pb.environment().putAll(env);
53+
Process process = pb.start();
54+
// new Thread(new ProcessReader(process.getInputStream())).start();
55+
// new Thread(new ProcessReader(process.getErrorStream())).start();
5256
return process;
5357
}
5458

5559
/**
56-
* Launches a process using the supplied arguments but does drain the IO
60+
* Launches a process using the supplied arguments but does not drain the IO
5761
*/
5862
static Process launchProcess(List<String> args, Map<String, String> env) throws IOException {
59-
Process process;
60-
if (env.isEmpty()) {
61-
process = Runtime.getRuntime().exec(args.toArray(new String[0]));
62-
} else {
63-
Map<String, String> currentEnv = System.getenv();
64-
Map<String, String> finalEnv = new HashMap<>(currentEnv);
65-
finalEnv.putAll(env);
66-
String[] envArray = new String[finalEnv.size()];
67-
int i = 0;
68-
for (var entry : finalEnv.entrySet()) {
69-
envArray[i] = entry.getKey() + "=" + entry.getValue();
70-
i++;
71-
}
72-
process = Runtime.getRuntime().exec(args.toArray(new String[0]), envArray);
73-
}
74-
return process;
63+
ProcessBuilder pb = new ProcessBuilder(args);
64+
pb.environment().putAll(env);
65+
return pb.start();
7566
}
7667

7768
/**
@@ -128,7 +119,7 @@ private static void ensureProcessIsAlive(Process quarkusProcess) {
128119
static void destroyProcess(Process quarkusProcess) {
129120
quarkusProcess.destroy();
130121
int i = 0;
131-
while (i++ < 10) {
122+
while (i++ < 200) {
132123
try {
133124
Thread.sleep(LOG_CHECK_INTERVAL);
134125
} catch (InterruptedException ignored) {

test-framework/junit5/src/main/java/io/quarkus/test/junit/launcher/JarLauncherProvider.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ public JarArtifactLauncher create(CreateContext context) {
5151
TestConfigUtil.argLineValues(testConfig.argLine().orElse("")),
5252
testConfig.env(),
5353
context.devServicesLaunchResult(),
54-
context.buildOutputDirectory().resolve(pathStr)));
54+
context.buildOutputDirectory().resolve(pathStr),
55+
config.getOptionalValue("quarkus.package.jar.appcds.use-aot", Boolean.class)
56+
.orElse(Boolean.FALSE)));
5557
return launcher;
5658
} else {
5759
throw new IllegalStateException("The path of the native binary could not be determined");
@@ -61,18 +63,26 @@ public JarArtifactLauncher create(CreateContext context) {
6163
static class DefaultJarInitContext extends DefaultInitContextBase implements JarArtifactLauncher.JarInitContext {
6264

6365
private final Path jarPath;
66+
private final boolean generateAotFile;
6467

6568
DefaultJarInitContext(int httpPort, int httpsPort, Duration waitTime, String testProfile,
6669
List<String> argLine, Map<String, String> env,
67-
ArtifactLauncher.InitContext.DevServicesLaunchResult devServicesLaunchResult, Path jarPath) {
70+
ArtifactLauncher.InitContext.DevServicesLaunchResult devServicesLaunchResult, Path jarPath,
71+
boolean generateAotFile) {
6872
super(httpPort, httpsPort, waitTime, testProfile, argLine, env, devServicesLaunchResult);
6973
this.jarPath = jarPath;
74+
this.generateAotFile = generateAotFile;
7075
}
7176

7277
@Override
7378
public Path jarPath() {
7479
return jarPath;
7580
}
81+
82+
@Override
83+
public boolean generateAotFile() {
84+
return generateAotFile;
85+
}
7686
}
7787

7888
}

0 commit comments

Comments
 (0)