1 /*
2 * Copyright (c) 2024, 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 // Experimental feature to allow special instrumentation code to be executed during training run:
26 //
27 // Example: app.jar -- Contains the classes for the real application.
28 // Entry point = the "App" class
29 // test.jar -- Instrumentation code to exercise the app or the framework.
30 // Entry point = the "TestDriver" class
31 //
32 // Training run:
33 //
34 // rm app.cds
35 // java -XX:CacheDataStore=app.cds -cp app.jar:test.jar -XX:CacheOnlyClassesIn=app.jar TestDriver
36 //
37 // All classes in test.jar will be excluded from app.cds
38 //
39 // Production run:
40 //
41 // java -XX:CacheDataStore=app.cds -cp app.jar:test.jar App
42 //
43 // TODO:
44 // Allow "-cp app.jar" to be used in production run, so test classes don't leaked into
45 // the production run.
46
47 /*
48 * @test id=static
49 * @summary test the -XX:CacheOnlyClassesIn flag with the classic static archive workflow
50 * @requires vm.cds
51 * @library /test/lib
52 * @run driver CacheOnlyClassesIn STATIC
53 */
54
55 /*
56 * @test id=dynamic
57 * @summary test the -XX:CacheOnlyClassesIn flag with the classic dynamic archive workflow
58 * @requires vm.cds
59 * @library /test/lib
60 * @build jdk.test.whitebox.WhiteBox
61 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
62 * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. CacheOnlyClassesIn DYNAMIC
63 */
64
65 /*
66 * @test id=aot
67 * @summary test the -XX:CacheOnlyClassesIn flag with JEP 483t workflow
68 * @requires vm.cds
69 * @requires vm.cds.write.archived.java.heap
70 * @library /test/lib
71 * @run driver CacheOnlyClassesIn AOT
72 */
73
74 import java.io.File;
75 import jdk.test.lib.cds.CDSAppTester;
76 import jdk.test.lib.helpers.ClassFileInstaller;
77 import jdk.test.lib.process.OutputAnalyzer;
78
79 public class CacheOnlyClassesIn {
80 static String mainClass = CacheOnlyClassesInApp.class.getName();
81 static String appJar, testJar;
82
83 public static void main(String args[]) throws Exception {
84 appJar = ClassFileInstaller.writeJar("app.jar",
85 "CacheOnlyClassesInApp");
86 testJar = ClassFileInstaller.writeJar("test.jar",
87 "TestHarness");
88 MyTester tester = new MyTester();
89 tester.run(args);
90 }
91
92 static class MyTester extends CDSAppTester {
93 public MyTester() {
94 super("CacheOnlyClassesInApp");
95 }
96
97 @Override
98 public String classpath(RunMode runMode) {
99 return appJar + File.pathSeparator + testJar;
100 }
101
102 @Override
103 public String[] vmArgs(RunMode runMode) {
104 return new String[] {
105 "-XX:CacheOnlyClassesIn=" + appJar,
106 };
107 }
108
109 @Override
110 public String[] appCommandLine(RunMode runMode) {
111 return new String[] {
112 mainClass,
113 };
114 }
115
116 @Override
117 public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception {
118 if (runMode == RunMode.DUMP_STATIC ||
119 runMode == RunMode.DUMP_DYNAMIC ||
120 runMode == RunMode.TRAINING) {
121 out.shouldContain("Skipping TestHarness: excluded via -XX:CacheOnlyClassesIn");
122 }
123 }
124 }
125 }
126
127 class CacheOnlyClassesInApp {
128 public static void main(String args[]) {
129 System.out.println("Hello World = " + TestHarness.doit());
130 }
131
132 static volatile int x;
133 public static int testLoop() {
134 for (int i = 0; i < 100000000; i++) {
135 x ^= (x + 39);
136 }
137 return x;
138 }
139 }
140
141 class TestHarness {
142 static int doit() {
143 return CacheOnlyClassesInApp.testLoop() + myTestLoop();
144 }
145
146 static volatile int x;
147 public static int myTestLoop() {
148 for (int i = 0; i < 100000000; i++) {
149 x ^= (x + 39);
150 }
151 return x;
152 }
153 }