1 /*
  2  * Copyright (c) 2020, 2023, 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  * @test id=default-cl
 26  * @requires vm.cds
 27  * @summary Test class loader constraint checks for archived classes (dynamic archive)
 28  * @library /test/lib
 29  *          /test/hotspot/jtreg/runtime/cds/appcds
 30  *          /test/hotspot/jtreg/runtime/cds/appcds/test-classes
 31  *          /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive
 32  * @modules java.base/jdk.internal.misc
 33  *          jdk.httpserver
 34  * @build jdk.test.whitebox.WhiteBox
 35  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 36  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DynamicLoaderConstraintsTest
 37  */
 38 
 39 /**
 40  * @test id=custom-cl
 41  * @requires vm.cds.custom.loaders
 42  * @summary Test class loader constraint checks for archived classes (dynamic archive) with custom class loader
 43  * @bug 8267347
 44  * @library /test/lib
 45  *          /test/hotspot/jtreg/runtime/cds/appcds
 46  *          /test/hotspot/jtreg/runtime/cds/appcds/test-classes
 47  *          /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive
 48  * @modules java.base/jdk.internal.misc
 49  *          jdk.httpserver
 50  * @build jdk.test.whitebox.WhiteBox
 51  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 52  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DynamicLoaderConstraintsTest custom
 53  */
 54 
 55 /**
 56  * @test id=custom-cl-zgc-singlegen
 57  * @requires vm.cds.custom.loaders
 58  * @requires vm.gc.ZSinglegen
 59  * @summary Test dumptime_table entries are removed with zgc eager class unloading
 60  * @bug 8274935
 61  * @library /test/lib
 62  *          /test/hotspot/jtreg/runtime/cds/appcds
 63  *          /test/hotspot/jtreg/runtime/cds/appcds/test-classes
 64  *          /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive
 65  * @modules java.base/jdk.internal.misc
 66  *          jdk.httpserver
 67  * @build jdk.test.whitebox.WhiteBox
 68  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 69  * @run main/othervm/timeout=180 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DynamicLoaderConstraintsTest custom-zgc
 70  */
 71 
 72 /**
 73  * @test id=custom-cl-zgc-generational
 74  * @requires vm.cds.custom.loaders
 75  * @requires vm.gc.ZGenerational
 76  * @summary Test dumptime_table entries are removed with zgc eager class unloading
 77  * @bug 8274935
 78  * @library /test/lib
 79  *          /test/hotspot/jtreg/runtime/cds/appcds
 80  *          /test/hotspot/jtreg/runtime/cds/appcds/test-classes
 81  *          /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive
 82  * @modules java.base/jdk.internal.misc
 83  *          jdk.httpserver
 84  * @build jdk.test.whitebox.WhiteBox
 85  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 86  * @run main/othervm/timeout=180 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DynamicLoaderConstraintsTest custom-zgc-generational
 87  */
 88 
 89 import com.sun.net.httpserver.HttpExchange;
 90 import com.sun.net.httpserver.HttpHandler;
 91 import jdk.test.lib.Asserts;
 92 import jdk.test.lib.helpers.ClassFileInstaller;
 93 import jdk.test.lib.Platform;
 94 
 95 public class DynamicLoaderConstraintsTest extends DynamicArchiveTestBase {
 96     static String mainClass = LoaderConstraintsApp.class.getName();
 97     static String appJar = null;
 98     static String appClasses[] = {
 99         mainClass,
100         HttpHandler.class.getName(),
101         HttpExchange.class.getName(),
102         Asserts.class.getName(),
103         MyHttpHandler.class.getName(),
104         MyHttpHandlerB.class.getName(),
105         MyHttpHandlerC.class.getName(),
106         MyClassLoader.class.getName()
107     };
108 
109     static String loaderMainClass = CustomAppLoader.class.getName();
110     static String loaderJar = null;
111     static String loaderClasses[] = {
112         loaderMainClass
113     };
114 
115     /*
116      * useCustomLoader: if true, load the LoaderConstraintsApp in a custom loader before executing it.
117      *                  if false, LoaderConstraintsApp will be loaded by the built-in AppClassLoader.
118      */
119     static boolean useCustomLoader;
120     static boolean useZGC;
121     static boolean useZGenerational;
122 
123     public static void main(String[] args) throws Exception {
124         useCustomLoader = (args.length != 0);
125         useZGenerational = (args.length != 0 && args[0].equals("custom-zgc-generational"));
126         useZGC = useZGenerational || (args.length != 0 && args[0].equals("custom-zgc"));
127         runTest(DynamicLoaderConstraintsTest::doTest);
128     }
129 
130     static void doTest() throws Exception  {
131         appJar = ClassFileInstaller.writeJar("loader_constraints.jar", appClasses);
132         if (useCustomLoader) {
133             loaderJar = ClassFileInstaller.writeJar("custom_app_loader.jar", loaderClasses);
134         }
135         doTest(false);
136         doTest(true);
137     }
138 
139     /*
140      * errorInDump:
141      * true:  Even when dumping the archive, execute the code that would cause
142      *        LinkageError, to see how the VM can handle such error during
143      *        dump time.
144      * false: At dump time, simply load all the necessary test classes without
145      *        causing LinkageError. This ensures the test classes will be
146      *        archived so we can test CDS's handling of loader constraints during
147      *        run time.
148      */
149   static void doTest(boolean errorInDump) throws Exception  {
150         for (int i = 1; i <= 3; i++) {
151             System.out.println("========================================");
152             System.out.println("errorInDump: " + errorInDump + ", useCustomLoader: " + useCustomLoader +
153                                ", useZGC: " + useZGC + ", ZGenerational: " + useZGenerational + ", case: " + i);
154             System.out.println("========================================");
155             String topArchiveName = getNewArchiveName();
156             String testCase = Integer.toString(i);
157             String cmdLine[] = new String[] {
158                 "--add-modules",
159                 "java.base,jdk.httpserver",
160                 "--add-exports",
161                 "java.base/jdk.internal.misc=ALL-UNNAMED",
162                 "-Xlog:cds=debug,class+load,class+loader+constraints",
163                 "-XX:-PreloadSharedClasses",
164             };
165 
166             if (useCustomLoader) {
167                 if (useZGC) {
168                     String zGenerational = "-XX:" + (useZGenerational ? "+" : "-") + "ZGenerational";
169                     // Add options to force eager class unloading.
170                     cmdLine = TestCommon.concat(cmdLine, "-cp", loaderJar,
171                                                 "-XX:+UseZGC", zGenerational, "-XX:ZCollectionInterval=0.01",
172                                                 loaderMainClass, appJar);
173                     setBaseArchiveOptions("-XX:+UseZGC", "-Xlog:cds");
174                 } else {
175                     cmdLine = TestCommon.concat(cmdLine, "-cp", loaderJar,
176                                                 loaderMainClass, appJar);
177                 }
178             } else {
179                 cmdLine = TestCommon.concat(cmdLine, "-cp", appJar);
180             }
181 
182             cmdLine = TestCommon.concat(cmdLine, mainClass, testCase);
183 
184             String[] dumpCmdLine = cmdLine;
185             if (!errorInDump) {
186                 dumpCmdLine = TestCommon.concat(dumpCmdLine, "loadClassOnly");
187             }
188 
189             dump(topArchiveName, dumpCmdLine).assertNormalExit();
190             run(topArchiveName, cmdLine).assertNormalExit();
191         }
192     }
193 }