8187118: Remove appending -cp path to the boot class path at AppCDS dump time
8187119: Consolidate record_shared_class_loader_type() and record_result()
Summary: Remove -cp path from the boot append list at dump time and other AppCDS cleanups.
Reviewed-by: lfoltan, iklam
--- a/src/hotspot/share/classfile/classLoader.cpp Fri Nov 17 20:56:14 2017 +0300
+++ b/src/hotspot/share/classfile/classLoader.cpp Sun Nov 19 23:30:41 2017 -0500
@@ -145,9 +145,9 @@
ClassPathEntry* ClassLoader::_jrt_entry = NULL;
ClassPathEntry* ClassLoader::_first_append_entry = NULL;
ClassPathEntry* ClassLoader::_last_append_entry = NULL;
-int ClassLoader::_num_entries = 0;
-int ClassLoader::_num_boot_entries = -1;
#if INCLUDE_CDS
+ClassPathEntry* ClassLoader::_app_classpath_entries = NULL;
+ClassPathEntry* ClassLoader::_last_app_classpath_entry = NULL;
GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL;
GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL;
SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
@@ -660,20 +660,18 @@
void ClassLoader::setup_bootstrap_search_path() {
const char* sys_class_path = Arguments::get_sysclasspath();
- const char* java_class_path = Arguments::get_appclasspath();
if (PrintSharedArchiveAndExit) {
// Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
// the same as the bootcp of the shared archive.
} else {
trace_class_path("bootstrap loader class path=", sys_class_path);
- trace_class_path("classpath: ", java_class_path);
}
#if INCLUDE_CDS
if (DumpSharedSpaces) {
_shared_paths_misc_info->add_boot_classpath(sys_class_path);
}
#endif
- setup_search_path(sys_class_path, true);
+ setup_boot_search_path(sys_class_path);
}
#if INCLUDE_CDS
@@ -691,6 +689,36 @@
delete checker;
return result;
}
+
+void ClassLoader::setup_app_search_path(const char *class_path) {
+
+ assert(DumpSharedSpaces, "Sanity");
+
+ Thread* THREAD = Thread::current();
+ int len = (int)strlen(class_path);
+ int end = 0;
+
+ // Iterate over class path entries
+ for (int start = 0; start < len; start = end) {
+ while (class_path[end] && class_path[end] != os::path_separator()[0]) {
+ end++;
+ }
+ EXCEPTION_MARK;
+ ResourceMark rm(THREAD);
+ char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
+ strncpy(path, &class_path[start], end - start);
+ path[end - start] = '\0';
+
+ check_shared_classpath(path);
+
+ update_class_path_entry_list(path, false, false);
+
+ while (class_path[end] == os::path_separator()[0]) {
+ end++;
+ }
+ }
+}
+
#endif
// Construct the array of module/path pairs as specified to --patch-module
@@ -764,10 +792,11 @@
return false;
}
-void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_search) {
+// Set up the _jrt_entry if present and boot append path
+void ClassLoader::setup_boot_search_path(const char *class_path) {
int len = (int)strlen(class_path);
int end = 0;
- bool set_base_piece = bootstrap_search;
+ bool set_base_piece = true;
// Iterate over class path entries
for (int start = 0; start < len; start = end) {
@@ -780,10 +809,10 @@
strncpy(path, &class_path[start], end - start);
path[end - start] = '\0';
- // The first time through the bootstrap_search setup, it must be determined
- // what the base or core piece of the boot loader search is. Either a java runtime
- // image is present or this is an exploded module build situation.
if (set_base_piece) {
+ // The first time through the bootstrap_search setup, it must be determined
+ // what the base or core piece of the boot loader search is. Either a java runtime
+ // image is present or this is an exploded module build situation.
assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, JAVA_BASE_NAME),
"Incorrect boot loader search path, no java runtime image or " JAVA_BASE_NAME " exploded build");
struct stat st;
@@ -797,13 +826,7 @@
assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice");
assert(new_entry != NULL && new_entry->is_modules_image(), "No java runtime image present");
_jrt_entry = new_entry;
- ++_num_entries;
-#if INCLUDE_CDS
- if (DumpSharedSpaces) {
- JImageFile *jimage = _jrt_entry->jimage();
- assert(jimage != NULL, "No java runtime image file present");
- }
-#endif
+ assert(_jrt_entry->jimage() != NULL, "No java runtime image");
}
} else {
// If path does not exist, exit
@@ -813,7 +836,7 @@
} else {
// Every entry on the system boot class path after the initial base piece,
// which is set by os::set_boot_path(), is considered an appended entry.
- update_class_path_entry_list(path, false, bootstrap_search);
+ update_class_path_entry_list(path, false, true);
}
#if INCLUDE_CDS
@@ -968,7 +991,7 @@
return false;
}
-void ClassLoader::add_to_list(ClassPathEntry *new_entry) {
+void ClassLoader::add_to_boot_append_entries(ClassPathEntry *new_entry) {
if (new_entry != NULL) {
if (_last_append_entry == NULL) {
assert(_first_append_entry == NULL, "boot loader's append class path entry list not empty");
@@ -978,11 +1001,48 @@
_last_append_entry = new_entry;
}
}
- _num_entries++;
}
-void ClassLoader::add_to_list(const char *apath) {
- update_class_path_entry_list((char*)apath, false, false);
+// Record the path entries specified in -cp during dump time. The recorded
+// information will be used at runtime for loading the archived app classes.
+//
+// Note that at dump time, ClassLoader::_app_classpath_entries are NOT used for
+// loading app classes. Instead, the app class are loaded by the
+// jdk/internal/loader/ClassLoaders$AppClassLoader instance.
+void ClassLoader::add_to_app_classpath_entries(const char* path,
+ ClassPathEntry* entry,
+ bool check_for_duplicates) {
+#if INCLUDE_CDS
+ assert(entry != NULL, "ClassPathEntry should not be NULL");
+ ClassPathEntry* e = _app_classpath_entries;
+ if (check_for_duplicates) {
+ while (e != NULL) {
+ if (strcmp(e->name(), entry->name()) == 0) {
+ // entry already exists
+ return;
+ }
+ e = e->next();
+ }
+ }
+
+ // The entry does not exist, add to the list
+ if (_app_classpath_entries == NULL) {
+ assert(_last_app_classpath_entry == NULL, "Sanity");
+ _app_classpath_entries = _last_app_classpath_entry = entry;
+ } else {
+ _last_app_classpath_entry->set_next(entry);
+ _last_app_classpath_entry = entry;
+ }
+
+ if (entry->is_jar_file()) {
+ ClassLoaderExt::process_jar_manifest(entry, check_for_duplicates);
+ } else {
+ if (!os::dir_is_empty(path)) {
+ tty->print_cr("Error: non-empty directory '%s'", path);
+ exit_with_path_failure("Cannot have non-empty directory in app classpaths", NULL);
+ }
+ }
+#endif
}
// Returns true IFF the file/dir exists and the entry was successfully created.
@@ -1002,8 +1062,10 @@
// Do not reorder the bootclasspath which would break get_system_package().
// Add new entry to linked list
- if (!check_for_duplicates || !contains_append_entry(new_entry->name())) {
- ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry);
+ if (is_boot_append) {
+ add_to_boot_append_entries(new_entry);
+ } else {
+ add_to_app_classpath_entries(path, new_entry, check_for_duplicates);
}
return true;
} else {
@@ -1323,6 +1385,7 @@
return NULL;
}
+// Called by the boot classloader to load classes
InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) {
assert(name != NULL, "invariant");
assert(THREAD->is_Java_thread(), "must be a JavaThread");
@@ -1402,11 +1465,6 @@
e = _first_append_entry;
while (e != NULL) {
- if (DumpSharedSpaces && classpath_index >= _num_boot_entries) {
- // Do not load any class from the app classpath using the boot loader. Let
- // the built-in app class laoder load them.
- break;
- }
stream = e->open_stream(file_name, CHECK_NULL);
if (!context.check(stream, classpath_index)) {
return NULL;
@@ -1442,7 +1500,11 @@
return NULL;
}
- return context.record_result(name, e, classpath_index, result, THREAD);
+ if (!add_package(file_name, classpath_index, THREAD)) {
+ return NULL;
+ }
+
+ return result;
}
#if INCLUDE_CDS
@@ -1465,7 +1527,9 @@
return source;
}
-void ClassLoader::record_shared_class_loader_type(InstanceKlass* ik, const ClassFileStream* stream) {
+// Record the shared classpath index and loader type for classes loaded
+// by the builtin loaders at dump time.
+void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream) {
assert(DumpSharedSpaces, "sanity");
assert(stream != NULL, "sanity");
@@ -1474,7 +1538,8 @@
return;
}
- if (stream->source() == NULL) {
+ char* src = (char*)stream->source();
+ if (src == NULL) {
if (ik->class_loader() == NULL) {
// JFR classes
ik->set_shared_classpath_index(0);
@@ -1486,56 +1551,42 @@
assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build");
ModuleEntry* module = ik->module();
- ClassPathEntry* e = NULL;
- int classpath_index = 0;
+ int classpath_index = -1;
+ ResourceMark rm;
+ char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN);
- // Check if the class is from the runtime image
- if (module != NULL && (module->location() != NULL) &&
- (module->location()->starts_with("jrt:"))) {
- e = _jrt_entry;
- classpath_index = 0;
- } else {
- classpath_index = 1;
- ResourceMark rm;
- char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN);
- for (e = _first_append_entry; e != NULL; e = e->next()) {
- if (get_canonical_path(e->name(), canonical_path, JVM_MAXPATHLEN)) {
- char* src = (char*)stream->source();
- // save the path from the file: protocol or the module name from the jrt: protocol
- // if no protocol prefix is found, src is the same as stream->source() after the following call
- src = skip_uri_protocol(src);
- if (strcmp(canonical_path, os::native_path((char*)src)) == 0) {
- break;
- }
- classpath_index ++;
+ // save the path from the file: protocol or the module name from the jrt: protocol
+ // if no protocol prefix is found, path is the same as stream->source()
+ char* path = skip_uri_protocol(src);
+ for (int i = 0; i < FileMapInfo::get_number_of_share_classpaths(); i++) {
+ SharedClassPathEntry* ent = FileMapInfo::shared_classpath(i);
+ if (get_canonical_path(ent->name(), canonical_path, JVM_MAXPATHLEN)) {
+ // If the path (from the class stream srouce) is the same as the shared
+ // class path, then we have a match. For classes from module image loaded by the
+ // PlatformClassLoader, the stream->source() is not the name of the module image.
+ // Need to look for 'jrt:' explicitly.
+ if (strcmp(canonical_path, os::native_path((char*)path)) == 0 ||
+ (i == 0 && string_starts_with(src, "jrt:"))) {
+ classpath_index = i;
+ break;
}
}
- if (e == NULL) {
- assert(ik->shared_classpath_index() < 0,
- "must be a class from a custom jar which isn't in the class path or boot class path");
- return;
- }
+ }
+ if (classpath_index < 0) {
+ // Shared classpath entry table only contains boot class path and -cp path.
+ // No path entry found for this class. Must be a shared class loaded by the
+ // user defined classloader.
+ assert(ik->shared_classpath_index() < 0, "Sanity");
+ return;
}
- if (classpath_index < _num_boot_entries) {
- // ik is either:
- // 1) a boot class loaded from the runtime image during vm initialization (classpath_index = 0); or
- // 2) a user's class from -Xbootclasspath/a (classpath_index > 0)
- // In the second case, the classpath_index, classloader_type will be recorded via
- // context.record_result() in ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS).
- if (classpath_index > 0) {
- return;
- }
- }
-
- ResourceMark rm;
const char* const class_name = ik->name()->as_C_string();
const char* const file_name = file_name_for_class_name(class_name,
ik->name()->utf8_length());
assert(file_name != NULL, "invariant");
Thread* THREAD = Thread::current();
ClassLoaderExt::Context context(class_name, file_name, CATCH);
- context.record_result(ik->name(), e, classpath_index, ik, THREAD);
+ context.record_result(ik->name(), classpath_index, ik, THREAD);
}
#endif // INCLUDE_CDS
@@ -1623,7 +1674,6 @@
#if INCLUDE_CDS
void ClassLoader::initialize_shared_path() {
if (DumpSharedSpaces) {
- _num_boot_entries = _num_entries;
ClassLoaderExt::setup_search_paths();
_shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
}
--- a/src/hotspot/share/classfile/classLoader.hpp Fri Nov 17 20:56:14 2017 +0300
+++ b/src/hotspot/share/classfile/classLoader.hpp Sun Nov 19 23:30:41 2017 -0500
@@ -237,14 +237,6 @@
// Last entry in linked list of appended ClassPathEntry instances
static ClassPathEntry* _last_append_entry;
- // Note: _num_entries includes the java runtime image and all
- // the entries on the _first_append_entry linked list.
- static int _num_entries;
-
- // number of entries in the boot class path including the
- // java runtime image
- static int _num_boot_entries;
-
// Array of module names associated with the boot class loader
CDS_ONLY(static GrowableArray<char*>* _boot_modules_array;)
@@ -254,12 +246,22 @@
// Info used by CDS
CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
+ CDS_ONLY(static ClassPathEntry* _app_classpath_entries;)
+ CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;)
+ CDS_ONLY(static void setup_app_search_path(const char *class_path);)
+ static void add_to_app_classpath_entries(const char* path,
+ ClassPathEntry* entry,
+ bool check_for_duplicates);
+ public:
+ CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})
+
+ protected:
// Initialization:
// - setup the boot loader's system class path
// - setup the boot loader's patch mod entries, if present
// - create the ModuleEntry for java.base
static void setup_bootstrap_search_path();
- static void setup_search_path(const char *class_path, bool setting_bootstrap);
+ static void setup_boot_search_path(const char *class_path);
static void setup_patch_mod_entries();
static void create_javabase();
@@ -395,7 +397,6 @@
static ClassPathEntry* classpath_entry(int n) {
assert(n >= 0, "sanity");
- assert(!has_jrt_entry() || n < _num_entries, "sanity");
if (n == 0) {
assert(has_jrt_entry(), "No class path entry at 0 for exploded module builds");
return ClassLoader::_jrt_entry;
@@ -414,15 +415,46 @@
}
}
- static int number_of_classpath_entries() {
- return _num_entries;
- }
-
static bool is_in_patch_mod_entries(Symbol* module_name);
#if INCLUDE_CDS
// Sharing dump and restore
+ // Helper function used by CDS code to get the number of boot classpath
+ // entries during shared classpath setup time.
+ static int num_boot_classpath_entries() {
+ assert(DumpSharedSpaces, "Should only be called at CDS dump time");
+ assert(has_jrt_entry(), "must have a java runtime image");
+ int num_entries = 1; // count the runtime image
+ ClassPathEntry* e = ClassLoader::_first_append_entry;
+ while (e != NULL) {
+ num_entries ++;
+ e = e->next();
+ }
+ return num_entries;
+ }
+
+ static ClassPathEntry* get_next_boot_classpath_entry(ClassPathEntry* e) {
+ if (e == ClassLoader::_jrt_entry) {
+ return ClassLoader::_first_append_entry;
+ } else {
+ return e->next();
+ }
+ }
+
+ // Helper function used by CDS code to get the number of app classpath
+ // entries during shared classpath setup time.
+ static int num_app_classpath_entries() {
+ assert(DumpSharedSpaces, "Should only be called at CDS dump time");
+ int num_entries = 0;
+ ClassPathEntry* e= ClassLoader::_app_classpath_entries;
+ while (e != NULL) {
+ num_entries ++;
+ e = e->next();
+ }
+ return num_entries;
+ }
+
static void check_shared_classpath(const char *path);
static void finalize_shared_paths_misc_info();
static int get_shared_paths_misc_info_size();
@@ -430,7 +462,7 @@
static bool check_shared_paths_misc_info(void* info, int size);
static void exit_with_path_failure(const char* error, const char* message);
- static void record_shared_class_loader_type(InstanceKlass* ik, const ClassFileStream* stream);
+ static void record_result(InstanceKlass* ik, const ClassFileStream* stream);
#endif
static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name,
const char* file_name, jlong &size);
@@ -446,20 +478,15 @@
static jlong class_link_count();
static jlong class_link_time_ms();
- static void set_first_append_entry(ClassPathEntry* entry);
-
// indicates if class path already contains a entry (exact match by name)
static bool contains_append_entry(const char* name);
- // adds a class path list
- static void add_to_list(ClassPathEntry* new_entry);
+ // adds a class path to the boot append entries
+ static void add_to_boot_append_entries(ClassPathEntry* new_entry);
// creates a class path zip entry (returns NULL if JAR file cannot be opened)
static ClassPathZipEntry* create_class_path_zip_entry(const char *apath, bool is_boot_append);
- // add a path to class path list
- static void add_to_list(const char* apath);
-
static bool string_ends_with(const char* str, const char* str_to_find);
// obtain package name from a fully qualified class name
--- a/src/hotspot/share/classfile/classLoaderExt.hpp Fri Nov 17 20:56:14 2017 +0300
+++ b/src/hotspot/share/classfile/classLoaderExt.hpp Sun Nov 19 23:30:41 2017 -0500
@@ -50,40 +50,28 @@
return false;
}
- InstanceKlass* record_result(Symbol* class_name,
- ClassPathEntry* e,
- const s2 classpath_index,
- InstanceKlass* result, TRAPS) {
- if (ClassLoader::add_package(_file_name, classpath_index, THREAD)) {
+ void record_result(Symbol* class_name,
+ const s2 classpath_index,
+ InstanceKlass* result, TRAPS) {
#if INCLUDE_CDS
- if (DumpSharedSpaces) {
- oop loader = result->class_loader();
- s2 classloader_type = ClassLoader::BOOT_LOADER;
- if (SystemDictionary::is_system_class_loader(loader)) {
- classloader_type = ClassLoader::APP_LOADER;
- ClassLoaderExt::set_has_app_classes();
- } else if (SystemDictionary::is_platform_class_loader(loader)) {
- classloader_type = ClassLoader::PLATFORM_LOADER;
- ClassLoaderExt::set_has_platform_classes();
- }
- result->set_shared_classpath_index(classpath_index);
- result->set_class_loader_type(classloader_type);
- }
+ assert(DumpSharedSpaces, "Sanity");
+ oop loader = result->class_loader();
+ s2 classloader_type = ClassLoader::BOOT_LOADER;
+ if (SystemDictionary::is_system_class_loader(loader)) {
+ classloader_type = ClassLoader::APP_LOADER;
+ ClassLoaderExt::set_has_app_classes();
+ } else if (SystemDictionary::is_platform_class_loader(loader)) {
+ classloader_type = ClassLoader::PLATFORM_LOADER;
+ ClassLoaderExt::set_has_platform_classes();
+ }
+ result->set_shared_classpath_index(classpath_index);
+ result->set_class_loader_type(classloader_type);
#endif
- return result;
- } else {
- return NULL;
- }
}
};
-
- static void add_class_path_entry(const char* path, bool check_for_duplicates,
- ClassPathEntry* new_entry) {
- ClassLoader::add_to_list(new_entry);
- }
static void append_boot_classpath(ClassPathEntry* new_entry) {
- ClassLoader::add_to_list(new_entry);
+ ClassLoader::add_to_boot_append_entries(new_entry);
}
static void setup_search_paths() {}
static bool is_boot_classpath(int classpath_index) {
@@ -96,6 +84,7 @@
static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
return NULL;
}
+ static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates) {}
#endif
};
--- a/src/hotspot/share/classfile/klassFactory.cpp Fri Nov 17 20:56:14 2017 +0300
+++ b/src/hotspot/share/classfile/klassFactory.cpp Sun Nov 19 23:30:41 2017 -0500
@@ -231,7 +231,7 @@
#if INCLUDE_CDS
if (DumpSharedSpaces) {
- ClassLoader::record_shared_class_loader_type(result, stream);
+ ClassLoader::record_result(result, stream);
#if INCLUDE_JVMTI
assert(cached_class_file == NULL, "Sanity");
// Archive the class stream data into the optional data section
--- a/src/hotspot/share/classfile/systemDictionary.cpp Fri Nov 17 20:56:14 2017 +0300
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Sun Nov 19 23:30:41 2017 -0500
@@ -1465,25 +1465,23 @@
// java.base packages in the boot loader's PackageEntryTable.
// No class outside of java.base is allowed to be loaded during
// this bootstrapping window.
- if (!DumpSharedSpaces) {
- if (pkg_entry == NULL || pkg_entry->in_unnamed_module()) {
- // Class is either in the unnamed package or in
- // a named package within the unnamed module. Either
- // case is outside of java.base, do not attempt to
- // load the class post java.base definition. If
- // java.base has not been defined, let the class load
- // and its package will be checked later by
- // ModuleEntryTable::verify_javabase_packages.
- if (ModuleEntryTable::javabase_defined()) {
- return NULL;
- }
- } else {
- // Check that the class' package is defined within java.base.
- ModuleEntry* mod_entry = pkg_entry->module();
- Symbol* mod_entry_name = mod_entry->name();
- if (mod_entry_name->fast_compare(vmSymbols::java_base()) != 0) {
- return NULL;
- }
+ if (pkg_entry == NULL || pkg_entry->in_unnamed_module()) {
+ // Class is either in the unnamed package or in
+ // a named package within the unnamed module. Either
+ // case is outside of java.base, do not attempt to
+ // load the class post java.base definition. If
+ // java.base has not been defined, let the class load
+ // and its package will be checked later by
+ // ModuleEntryTable::verify_javabase_packages.
+ if (ModuleEntryTable::javabase_defined()) {
+ return NULL;
+ }
+ } else {
+ // Check that the class' package is defined within java.base.
+ ModuleEntry* mod_entry = pkg_entry->module();
+ Symbol* mod_entry_name = mod_entry->name();
+ if (mod_entry_name->fast_compare(vmSymbols::java_base()) != 0) {
+ return NULL;
}
}
} else {
@@ -1501,7 +1499,7 @@
// Prior to bootstrapping's module initialization, never load a class outside
// of the boot loader's module path
- assert(Universe::is_module_initialized() || DumpSharedSpaces ||
+ assert(Universe::is_module_initialized() ||
!search_only_bootloader_append,
"Attempt to load a class outside of boot loader's module path");
--- a/src/hotspot/share/memory/filemap.cpp Fri Nov 17 20:56:14 2017 +0300
+++ b/src/hotspot/share/memory/filemap.cpp Sun Nov 19 23:30:41 2017 -0500
@@ -266,32 +266,55 @@
}
void FileMapInfo::allocate_classpath_entry_table() {
+ assert(DumpSharedSpaces, "Sanity");
+
Thread* THREAD = Thread::current();
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+ ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
+
+ assert(jrt != NULL,
+ "No modular java runtime image present when allocating the CDS classpath entry table");
+
size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
- int num_entries = ClassLoader::number_of_classpath_entries();
+ int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
+ int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
+ int num_entries = num_boot_classpath_entries + num_app_classpath_entries;
size_t bytes = entry_size * num_entries;
_classpath_entry_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
_classpath_entry_table_size = num_entries;
_classpath_entry_size = entry_size;
- assert(ClassLoader::get_jrt_entry() != NULL,
- "No modular java runtime image present when allocating the CDS classpath entry table");
-
- for (int i=0; i<num_entries; i++) {
- ClassPathEntry *cpe = ClassLoader::classpath_entry(i);
- const char* type = ((i == 0) ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
-
+ // 1. boot class path
+ int i = 0;
+ ClassPathEntry* cpe = jrt;
+ while (cpe != NULL) {
+ const char* type = ((cpe == jrt) ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
SharedClassPathEntry* ent = shared_classpath(i);
ent->init(cpe->name(), THREAD);
-
- if (i > 0) { // No need to do jimage.
+ if (cpe != jrt) { // No need to do jimage.
EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
SharedClassUtil::update_shared_classpath(cpe, ent, THREAD);
}
+ cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
+ i++;
}
+ assert(i == num_boot_classpath_entries,
+ "number of boot class path entry mismatch");
+
+ // 2. app class path
+ ClassPathEntry *acpe = ClassLoader::app_classpath_entries();
+ while (acpe != NULL) {
+ log_info(class, path)("add app shared path %s", acpe->name());
+ SharedClassPathEntry* ent = shared_classpath(i);
+ ent->init(acpe->name(), THREAD);
+ EXCEPTION_MARK;
+ SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
+ acpe = acpe->next();
+ i ++;
+ }
+ assert(i == num_entries, "number of app class path entry mismatch");
}
bool FileMapInfo::validate_classpath_entry_table() {