1 /*
2 * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 /*
26 * @test
27 * @summary JDK_AOT_VM_OPTIONS environment variable
28 * @requires vm.cds
29 * @requires vm.flagless
30 * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes
31 * @build Hello
32 * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello
33 * @run driver AOTToolOptions
34 */
35
36 import java.io.File;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import jdk.test.lib.cds.CDSTestUtils;
40 import jdk.test.lib.helpers.ClassFileInstaller;
41 import jdk.test.lib.process.OutputAnalyzer;
42 import jdk.test.lib.process.ProcessTools;
43
44 public class AOTToolOptions {
45 static String appJar = ClassFileInstaller.getJarPath("hello.jar");
46 static String aotConfigFile = "hello.aotconfig";
47 static String aotCacheFile = "hello.aot";
48 static String helloClass = "Hello";
49
50 public static void main(String[] args) throws Exception {
51 //----------------------------------------------------------------------
52 printTestCase("JDK_AOT_VM_OPTIONS (one-command training)");
53
54 ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
55 "-XX:AOTMode=record",
56 "-XX:AOTCacheOutput=" + aotCacheFile,
57 "-Xlog:aot=debug",
58 "-cp", appJar, helloClass);
59 // The "-Xshare:off" below should be treated as part of a property value and not
60 // a VM option by itself
61 pb.environment().put("JDK_AOT_VM_OPTIONS", "-Dsome.option='foo -Xshare:off ' -Xmx512m -XX:-AOTClassLinking");
62 OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "ontstep-train");
63 out.shouldContain("Hello World");
64 out.shouldContain("AOTCache creation is complete: hello.aot");
65 out.shouldContain("Picked up JDK_AOT_VM_OPTIONS: -Dsome.option='foo -Xshare:off '");
66 checkAOTClassLinkingDisabled(out);
67
68 //----------------------------------------------------------------------
69 printTestCase("JDK_AOT_VM_OPTIONS (two-command training)");
70 pb = ProcessTools.createLimitedTestJavaProcessBuilder(
71 "-XX:AOTMode=record",
72 "-XX:AOTConfiguration=" + aotConfigFile,
73 "-Xlog:aot=debug",
74 "-cp", appJar, helloClass);
75
76 out = CDSTestUtils.executeAndLog(pb, "train");
77 out.shouldContain("Hello World");
78 out.shouldContain("AOTConfiguration recorded: " + aotConfigFile);
79 out.shouldHaveExitValue(0);
80
81 //----------------------------------------------------------------------
82 pb = ProcessTools.createLimitedTestJavaProcessBuilder(
83 "-XX:AOTMode=create",
84 "-XX:AOTConfiguration=" + aotConfigFile,
85 "-XX:AOTCache=" + aotCacheFile,
86 "-Xlog:aot",
87 "-cp", appJar);
88 pb.environment().put("JDK_AOT_VM_OPTIONS", "-XX:-AOTClassLinking");
89 out = CDSTestUtils.executeAndLog(pb, "asm");
90 out.shouldContain("Picked up JDK_AOT_VM_OPTIONS:");
91 checkAOTClassLinkingDisabled(out);
92
93 //----------------------------------------------------------------------
94 printTestCase("JDK_AOT_VM_OPTIONS (with AOTMode specified in -XX:VMOptionsFile)");
95 String optionsFile = "opts.txt";
96 Files.writeString(Path.of(optionsFile), "-XX:AOTMode=create");
97
98 pb = ProcessTools.createLimitedTestJavaProcessBuilder(
99 "-XX:VMOptionsFile=" + optionsFile,
100 "-XX:AOTConfiguration=" + aotConfigFile,
101 "-XX:AOTCache=" + aotCacheFile,
102 "-Xlog:aot",
103 "-cp", appJar);
104 pb.environment().put("JDK_AOT_VM_OPTIONS", "-XX:-AOTClassLinking");
105 out = CDSTestUtils.executeAndLog(pb, "asm");
106 out.shouldContain("Picked up JDK_AOT_VM_OPTIONS:");
107 checkAOTClassLinkingDisabled(out);
108
109 //----------------------------------------------------------------------
110 printTestCase("Using -XX:VMOptionsFile inside JDK_AOT_VM_OPTIONS)");
111 Files.writeString(Path.of(optionsFile), "-XX:-AOTClassLinking");
112
113 pb = ProcessTools.createLimitedTestJavaProcessBuilder(
114 "-XX:AOTMode=create",
115 "-XX:AOTConfiguration=" + aotConfigFile,
116 "-XX:AOTCache=" + aotCacheFile,
117 "-Xlog:aot",
118 "-cp", appJar);
119 pb.environment().put("JDK_AOT_VM_OPTIONS", "-XX:VMOptionsFile=" + optionsFile);
120 out = CDSTestUtils.executeAndLog(pb, "asm");
121 out.shouldContain("Picked up JDK_AOT_VM_OPTIONS:");
122 checkAOTClassLinkingDisabled(out);
123 }
124
125 static void checkAOTClassLinkingDisabled(OutputAnalyzer out) {
126 out.shouldMatch("aot-linked =[ ]+0,"); // -XX:-AOTClassLinking should take effect
127 out.shouldNotMatch("aot-linked =[ ]+[1-9]");
128 out.shouldHaveExitValue(0);
129 }
130
131 static int testNum = 0;
132 static void printTestCase(String s) {
133 System.out.println("vvvvvvv TEST CASE " + testNum + ": " + s + ": starts here vvvvvvv");
134 testNum++;
135 }
136 }