2525/*
2626 * @test
2727 * @summary Test AOT cache support for array classes in custom class loaders.
28- * @bug 8353298
28+ * @bug 8353298 8356838
2929 * @requires vm.cds.supports.aot.class.linking
3030 * @comment work around JDK-8345635
3131 * @requires !vm.jvmci.enabled
3737 * @run driver AOTCacheSupportForCustomLoaders AOT
3838 */
3939
40+ import java .lang .module .Configuration ;
41+ import java .lang .module .ModuleFinder ;
4042import java .net .URL ;
4143import java .net .URLClassLoader ;
4244import java .io .File ;
45+ import java .nio .file .Path ;
46+ import java .nio .file .Paths ;
47+ import java .util .Set ;
48+ import jdk .test .lib .cds .CDSJarUtils ;
49+ import jdk .test .lib .cds .CDSModulePackager ;
4350import jdk .test .lib .cds .SimpleCDSAppTester ;
4451import jdk .test .lib .process .OutputAnalyzer ;
4552
4653public class AOTCacheSupportForCustomLoaders {
54+ static final Path SRC = Paths .get (System .getProperty ("test.src" )).resolve ("modules" );
55+
4756 public static void main (String ... args ) throws Exception {
57+ CDSModulePackager modulePackager = new CDSModulePackager (SRC );
58+ String modulePath = modulePackager .getOutputDir ().toString ();
59+ modulePackager .createModularJar ("com.test" );
60+
4861 SimpleCDSAppTester .of ("AOTCacheSupportForCustomLoaders" )
4962 .classpath ("app.jar" )
50- .addVmArgs ("-Xlog:cds+class=debug" , "-Xlog:cds" )
51- .appCommandLine ("AppWithCustomLoaders" )
63+ .addVmArgs ("-Xlog:cds+class=debug" , "-Xlog:cds" ,
64+ "--module-path=" + modulePath ,
65+ "--add-modules=com.test" )
66+ .appCommandLine ("AppWithCustomLoaders" , modulePath )
5267 .setAssemblyChecker ((OutputAnalyzer out ) -> {
5368 out .shouldMatch ("cds,class.*unreg AppWithCustomLoaders[$]MyLoadeeA" )
69+ .shouldMatch ("cds,class.*unreg com.test.Foo" )
5470 .shouldMatch ("cds,class.*array \\ [LAppWithCustomLoaders[$]MyLoadeeA;" )
5571 .shouldNotMatch ("cds,class.* ReturnIntegerAsString" );
5672 })
@@ -67,11 +83,21 @@ public static void main(String args[]) throws Exception {
6783 URL [] urls = new URL [] {custJar .toURI ().toURL ()};
6884 MyLoader loader = new MyLoader (urls , AppWithCustomLoaders .class .getClassLoader ());
6985
70- // Test 1: array class of MyLoadeeA (JDK-8353298)
86+ test1 (loader );
87+ test2 (loader );
88+ test3 (args [0 ]);
89+
90+ // TODO: more test cases JDK-8354557
91+ }
92+
93+ // Test 1: array class of MyLoadeeA (JDK-8353298)
94+ static void test1 (MyLoader loader ) throws Exception {
7195 Class klass = loader .loadClass ("AppWithCustomLoaders$MyLoadeeA" );
7296 klass .newInstance ();
97+ }
7398
74- // Test 2: VerificationType::is_reference_assignable_from() cannot be skipped (JDK-8356407)
99+ // Test 2: VerificationType::is_reference_assignable_from() cannot be skipped (JDK-8356407)
100+ static void test2 (MyLoader loader ) throws Exception {
75101 try {
76102 Class bad = loader .loadClass ("ReturnIntegerAsString" );
77103 Object o = bad .newInstance (); // force verification
@@ -80,8 +106,41 @@ public static void main(String args[]) throws Exception {
80106 } catch (VerifyError ve ) {
81107 System .out .println ("Expected: " + ve );
82108 }
109+ }
83110
84- // TODO: more test cases JDK-8354557
111+ // Test 3: custom loader defines a class from the exact location as a class defined in the boot layer.
112+ static void test3 (String modulePath ) throws Exception {
113+ Class <?> c0 = Class .forName ("com.test.Foo" );
114+ System .out .println (c0 );
115+ System .out .println (System .identityHashCode (c0 .getModule ()));
116+ System .out .println (c0 .getModule ().getName ());
117+ System .out .println (c0 .getClassLoader ());
118+
119+ // Regression test for JDK-8356838
120+ //
121+ // We create a new layer that loads the com.test module from the modulePath into
122+ // a different class loader.
123+ ModuleFinder finder = ModuleFinder .of (Paths .get (modulePath ));
124+ ModuleLayer parent = ModuleLayer .boot ();
125+ Configuration cf = parent .configuration ().resolve (finder , ModuleFinder .of (), Set .of ("com.test" ));
126+ ClassLoader scl = ClassLoader .getSystemClassLoader ();
127+ ModuleLayer layer = parent .defineModulesWithOneLoader (cf , scl );
128+ Class <?> c1 = layer .findLoader ("com.test" ).loadClass ("com.test.Foo" );
129+
130+ System .out .println (c1 );
131+ System .out .println (System .identityHashCode (c1 .getModule ()));
132+ System .out .println (c1 .getModule ().getName ());
133+ System .out .println (c1 .getClassLoader ());
134+
135+ if (!c1 .getModule ().getName ().equals ("com.test" )) {
136+ throw new RuntimeException ("Unexpected module: " + c1 .getModule ());
137+ }
138+ if (c1 .getModule () == c0 .getModule ()) {
139+ throw new RuntimeException ("Unexpected module: " + c1 .getModule ());
140+ }
141+ if (c1 .getClassLoader () == c0 .getClassLoader ()) {
142+ throw new RuntimeException ("Unexpected class loader: " + c1 .getClassLoader ());
143+ }
85144 }
86145
87146 public static class MyLoader extends URLClassLoader {
0 commit comments