bool FileMapInfo::validate_classpath_entry_table() { _validating_classpath_entry_table = true; int count = _header->_classpath_entry_table_size; _classpath_entry_table = _header->_classpath_entry_table; _classpath_entry_size = _header->_classpath_entry_size; for (int i=0; i<count; i++) { SharedClassPathEntry* ent = shared_classpath(i); struct stat st; const char* name = ent->_name; bool ok = true; if (TraceClassPaths || (TraceClassLoading && Verbose)) { tty->print_cr("[Checking shared classpath entry: %s]", name); } if (os::stat(name, &st) != 0) { fail_continue("Required classpath entry does not exist: %s", name); ok = false; } else if (ent->is_dir()) { if (!os::dir_is_empty(name)) { fail_continue("directory is not empty: %s", name); ok = false; } } else { if (ent->_timestamp != st.st_mtime || ent->_filesize != st.st_size) { ok = false; if (PrintSharedArchiveAndExit) { fail_continue(ent->_timestamp != st.st_mtime ? "Timestamp mismatch" : "File size mismatch"); } else { fail_continue("A jar file is not the one used while building" " the shared archive file: %s", name); } } } if (ok) { if (TraceClassPaths || (TraceClassLoading && Verbose)) { tty->print_cr("[ok]"); } } else if (!PrintSharedArchiveAndExit) { _validating_classpath_entry_table = false; return false; } } _classpath_entry_table_size = _header->_classpath_entry_table_size; _validating_classpath_entry_table = false; return true; }
void FileMapInfo::allocate_classpath_entry_table() { int bytes = 0; int count = 0; char* strptr = NULL; char* strptr_max = NULL; Thread* THREAD = Thread::current(); ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); for (int pass=0; pass<2; pass++) { ClassPathEntry *cpe = ClassLoader::classpath_entry(0); for (int cur_entry = 0 ; cpe != NULL; cpe = cpe->next(), cur_entry++) { const char *name = cpe->name(); int name_bytes = (int)(strlen(name) + 1); if (pass == 0) { count ++; bytes += (int)entry_size; bytes += name_bytes; if (TraceClassPaths || (TraceClassLoading && Verbose)) { tty->print_cr("[Add main shared path (%s) %s]", (cpe->is_jar_file() ? "jar" : "dir"), name); } } else { SharedClassPathEntry* ent = shared_classpath(cur_entry); if (cpe->is_jar_file()) { struct stat st; if (os::stat(name, &st) != 0) { // The file/dir must exist, or it would not have been added // into ClassLoader::classpath_entry(). // // If we can't access a jar file in the boot path, then we can't // make assumptions about where classes get loaded from. FileMapInfo::fail_stop("Unable to open jar file %s.", name); } EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. SharedClassUtil::update_shared_classpath(cpe, ent, st.st_mtime, st.st_size, THREAD); } else { ent->_filesize = -1; if (!os::dir_is_empty(name)) { ClassLoader::exit_with_path_failure("Cannot have non-empty directory in archived classpaths", name); } } ent->_name = strptr; if (strptr + name_bytes <= strptr_max) { strncpy(strptr, name, (size_t)name_bytes); // name_bytes includes trailing 0. strptr += name_bytes; } else { assert(0, "miscalculated buffer size"); } } } if (pass == 0) { EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. Array<u8>* arr = MetadataFactory::new_array<u8>(loader_data, (bytes + 7)/8, THREAD); strptr = (char*)(arr->data()); strptr_max = strptr + bytes; SharedClassPathEntry* table = (SharedClassPathEntry*)strptr; strptr += entry_size * count; _classpath_entry_table_size = count; _classpath_entry_table = table; _classpath_entry_size = entry_size; } } }
for (int pass=0; pass<2; pass++) { // Process the modular java runtime image first ClassPathEntry* jrt_entry = ClassLoader::get_jrt_entry(); assert(jrt_entry != NULL, "No modular java runtime image present when allocating the CDS classpath entry table"); const char *name = jrt_entry->name(); int name_bytes = (int)(strlen(name) + 1); if (pass == 0) { count++; bytes += (int)entry_size; bytes += name_bytes; log_info(class, path)("add main shared path for modular java runtime image %s", name); } else { // The java runtime image is always in slot 0 on the shared class path. SharedClassPathEntry* ent = shared_classpath(0); struct stat st; if (os::stat(name, &st) == 0) { ent->_timestamp = st.st_mtime; ent->_filesize = st.st_size; } if (ent->_filesize == 0) { // unknown ent->_filesize = -2; } ent->_name = strptr; assert(strptr + name_bytes <= strptr_max, "miscalculated buffer size"); strncpy(strptr, name, (size_t)name_bytes); // name_bytes includes trailing 0. strptr += name_bytes; }