1 /*
2  * Copyright (c) 2016, 2018, 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 ClassLoadUnloadTest
27  * @bug 8142506
28  * @requires vm.opt.final.ClassUnloading
29  * @modules java.base/jdk.internal.misc
30  * @library /test/lib /runtime/testlibrary
31  * @library classes
32  * @build test.Empty
33  * @run driver ClassLoadUnloadTest
34  */
35 
36 import jdk.test.lib.process.ProcessTools;
37 import jdk.test.lib.process.OutputAnalyzer;
38 import java.lang.ref.WeakReference;
39 import java.lang.reflect.Method;
40 import java.util.ArrayList;
41 import java.util.Collections;
42 import java.util.List;
43 
44 public class ClassLoadUnloadTest {
45     private static OutputAnalyzer out;
46     private static ProcessBuilder pb;
47     private static class ClassUnloadTestMain {
main(String... args)48         public static void main(String... args) throws Exception {
49             String className = "test.Empty";
50             ClassLoader cl = ClassUnloadCommon.newClassLoader();
51             Class<?> c = cl.loadClass(className);
52             cl = null; c = null;
53             ClassUnloadCommon.triggerUnloading();
54         }
55     }
56 
checkFor(String... outputStrings)57     static void checkFor(String... outputStrings) throws Exception {
58         out = new OutputAnalyzer(pb.start());
59         for (String s: outputStrings) {
60             out.shouldContain(s);
61         }
62         out.shouldHaveExitValue(0);
63     }
64 
checkAbsent(String... outputStrings)65     static void checkAbsent(String... outputStrings) throws Exception {
66         out = new OutputAnalyzer(pb.start());
67         for (String s: outputStrings) {
68             out.shouldNotContain(s);
69         }
70         out.shouldHaveExitValue(0);
71     }
72 
73     // Use the same command-line heap size setting as ../ClassUnload/UnloadTest.java
exec(String... args)74     static ProcessBuilder exec(String... args) throws Exception {
75         List<String> argsList = new ArrayList<>();
76         Collections.addAll(argsList, args);
77         Collections.addAll(argsList, "-Xmn8m");
78         Collections.addAll(argsList, "-Dtest.class.path=" + System.getProperty("test.class.path", "."));
79         Collections.addAll(argsList, ClassUnloadTestMain.class.getName());
80         return ProcessTools.createJavaProcessBuilder(argsList.toArray(new String[argsList.size()]));
81     }
82 
main(String... args)83     public static void main(String... args) throws Exception {
84 
85         //  -Xlog:class+unload=info
86         pb = exec("-Xlog:class+unload=info");
87         checkFor("[class,unload]", "unloading class");
88 
89         //  -Xlog:class+unload=off
90         pb = exec("-Xlog:class+unload=off");
91         checkAbsent("[class,unload]");
92 
93         //  -XX:+TraceClassUnloading
94         pb = exec("-XX:+TraceClassUnloading");
95         checkFor("[class,unload]", "unloading class");
96 
97         //  -XX:-TraceClassUnloading
98         pb = exec("-XX:-TraceClassUnloading");
99         checkAbsent("[class,unload]");
100 
101         //  -Xlog:class+load=info
102         pb = exec("-Xlog:class+load=info");
103         checkFor("[class,load]", "java.lang.Object", "source:");
104 
105         //  -Xlog:class+load=debug
106         pb = exec("-Xlog:class+load=debug");
107         checkFor("[class,load]", "java.lang.Object", "source:", "klass:", "super:", "loader:", "bytes:");
108 
109         //  -Xlog:class+load=off
110         pb = exec("-Xlog:class+load=off");
111         checkAbsent("[class,load]");
112 
113         //  -XX:+TraceClassLoading
114         pb = exec("-XX:+TraceClassLoading");
115         checkFor("[class,load]", "java.lang.Object", "source:");
116 
117         //  -XX:-TraceClassLoading
118         pb = exec("-XX:-TraceClassLoading");
119         checkAbsent("[class,load]");
120 
121         //  -verbose:class
122         pb = exec("-verbose:class");
123         checkFor("[class,load]", "java.lang.Object", "source:");
124         checkFor("[class,unload]", "unloading class");
125 
126         //  -Xlog:class+loader+data=trace
127         pb = exec("-Xlog:class+loader+data=trace");
128         checkFor("[class,loader,data]", "create loader data");
129 
130     }
131 }
132