--- old/src/hotspot/share/classfile/systemDictionary.cpp 2020-05-29 21:12:02.155898960 -0700 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2020-05-29 21:12:01.855887667 -0700 @@ -1228,6 +1228,7 @@ InstanceKlass* SystemDictionary::load_shared_boot_class(Symbol* class_name, PackageEntry* pkg_entry, TRAPS) { + assert(UseSharedSpaces, "Sanity check"); InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name); if (ik != NULL && ik->is_shared_boot_class()) { return load_shared_class(ik, Handle(), Handle(), NULL, pkg_entry, THREAD); @@ -1235,6 +1236,28 @@ return NULL; } +// Check if +// 1) -Xbootclasspath/a: specified or +// 2) --module-path at runtime +// so avoid checking class visibility for builtin loaders. +bool continue_check_shared_class_visibility() { + static int check_continue = -1; + if (check_continue == -1) { + const char *classpath_append = Arguments::get_jdk_boot_class_path_append(); + const char *module_path = Arguments::get_property("jdk.module.path"); + log_info(cds)("-Xbootclasspath/a: = %s", classpath_append != NULL ? classpath_append : "nil"); + log_info(cds)("--module-path = %s", module_path != NULL ? module_path : "nil"); + if ((classpath_append == NULL || strlen(classpath_append) == 0) && + (module_path == NULL || strlen(module_path) == 0)) { + check_continue = 0; + } else { + check_continue = 1; + } + } + return check_continue == 1; +} + + // Check if a shared class can be loaded by the specific classloader: // // NULL classloader: @@ -1245,6 +1268,23 @@ InstanceKlass* ik, PackageEntry* pkg_entry, Handle class_loader, TRAPS) { + bool cont = continue_check_shared_class_visibility(); +#ifdef ASSERT + if (!cont) { + assert(SystemDictionary::is_shared_class_visible_impl(class_name, ik, pkg_entry, class_loader, THREAD), "Sanity check"); + } +#endif + if (!cont) { + return true; + } + return is_shared_class_visible_impl(class_name, ik, pkg_entry, class_loader, THREAD); +} + +bool SystemDictionary::is_shared_class_visible_impl(Symbol* class_name, + InstanceKlass* ik, + PackageEntry* pkg_entry, + Handle class_loader, TRAPS) { + assert(!ModuleEntryTable::javabase_moduleEntry()->is_patched(), "Cannot use sharing if java.base is patched"); ResourceMark rm(THREAD); @@ -1556,12 +1596,14 @@ // Search for classes in the CDS archive. InstanceKlass* k = NULL; - { + #if INCLUDE_CDS + if (UseSharedSpaces) + { PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time()); k = load_shared_boot_class(class_name, pkg_entry, THREAD); -#endif } +#endif if (k == NULL) { // Use VM class loader --- old/src/hotspot/share/classfile/systemDictionary.hpp 2020-05-29 21:12:02.719920191 -0700 +++ new/src/hotspot/share/classfile/systemDictionary.hpp 2020-05-29 21:12:02.423909048 -0700 @@ -631,6 +631,9 @@ static bool is_shared_class_visible(Symbol* class_name, InstanceKlass* ik, PackageEntry* pkg_entry, Handle class_loader, TRAPS); + static bool is_shared_class_visible_impl(Symbol* class_name, InstanceKlass* ik, + PackageEntry* pkg_entry, + Handle class_loader, TRAPS); static bool check_shared_class_super_type(InstanceKlass* child, InstanceKlass* super, Handle class_loader, Handle protection_domain, bool is_superclass, TRAPS); --- old/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP.java 2020-05-29 21:12:03.267940819 -0700 +++ new/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP.java 2020-05-29 21:12:02.967929526 -0700 @@ -104,7 +104,7 @@ "--module-path", moduleDir.toString(), "-m", MAIN_MODULE); TestCommon.checkDump(output); - String prefix[] = {"-Djava.class.path=", "-Xlog:class+load=trace"}; + String prefix[] = {"-Djava.class.path=", "-Xlog:cds,class+load=trace"}; prefix = TestCommon.concat(prefix, extra_runtime_args); // run with the archive with the --module-path the same as the one during @@ -115,7 +115,8 @@ MAIN_MODULE) // -m .assertNormalExit(out -> { out.shouldContain("[class,load] com.greetings.Main source: shared objects file") - .shouldContain("[class,load] org.astro.World source: shared objects file"); + .shouldContain("[class,load] org.astro.World source: shared objects file") + .shouldContain("--module-path = " + moduleDir.toString()); }); // run with the archive with the --module-path different from the one during @@ -126,7 +127,8 @@ MAIN_MODULE) // -m .assertNormalExit(out -> { out.shouldMatch(".class.load. com.greetings.Main source:.*com.greetings.jar") - .shouldMatch(".class.load. org.astro.World source:.*org.astro.jar"); + .shouldMatch(".class.load. org.astro.World source:.*org.astro.jar") + .shouldContain("--module-path = " + moduleDir2.toString()); }); // create an archive with modular jar files in both -cp and --module-path @@ -143,24 +145,26 @@ // during dump time, the classes in the jar files after the -cp won't be // archived. Therefore, the classes won't be loaded from the archive but // will be loaded from the jar files. - TestCommon.run("-Xlog:class+load=trace", + TestCommon.run("-Xlog:cds,class+load=trace", "-cp", jars, "--module-path", moduleDir.toString(), MAIN_CLASS, "-m", MAIN_MODULE) .assertNormalExit(out -> { out.shouldMatch(".class.load. com.greetings.Main source:.*com.greetings.jar") - .shouldMatch(".class.load. org.astro.World source:.*org.astro.jar"); + .shouldMatch(".class.load. org.astro.World source:.*org.astro.jar") + .shouldContain("--module-path = " + moduleDir.toString()); }); // similar to the above case but without the main class name. The classes // should be loaded from the archive. - TestCommon.run("-Xlog:class+load=trace", + TestCommon.run("-Xlog:cds,class+load=trace", "-cp", jars, "--module-path", moduleDir.toString(), "-m", MAIN_MODULE) .assertNormalExit( "[class,load] com.greetings.Main source: shared objects file", - "[class,load] org.astro.World source: shared objects file"); + "[class,load] org.astro.World source: shared objects file", + "--module-path = " + moduleDir.toString()); // create an archive with two modular jars in the --module-path output = TestCommon.createArchive( @@ -173,15 +177,29 @@ // org.astro module in a different location. // The org.astro.World class should be loaded from the jar. // The Main class should still be loaded from the archive. - jars = destJar.toString() + System.getProperty("path.separator") + + final String mjars = destJar.toString() + System.getProperty("path.separator") + mainJar.toString(); TestCommon.runWithModules(prefix, null, // --upgrade-module-path - jars, // --module-path + mjars, // --module-path MAIN_MODULE) // -m .assertNormalExit(out -> { out.shouldContain("[class,load] com.greetings.Main source: shared objects file") - .shouldMatch(".class.load. org.astro.World source:.*org.astro.jar"); + .shouldMatch(".class.load. org.astro.World source:.*org.astro.jar") + .shouldContain("--module-path = " + mjars); }); + // run with CDS off, '--module-path = ' should not be printed out on output + TestCommon.run("-Xshare:off", + "-Xlog:cds,class+load=trace", + "-cp", mjars, + "--module-path", mjars, + "-m", + MAIN_MODULE) + .assertNormalExit(out -> { + out.shouldMatch(".class,load. com.greetings.Main source: .*com.greetings.jar") + .shouldMatch(".class.load. org.astro.World source:.*org.astro.jar") + .shouldNotContain("--module-path = " + mjars); + }); + } }