8345936: Call ClassLoader.getResourceAsByteArray only for multi-release jar

Reviewed-by: iklam, dholmes
This commit is contained in:
Calvin Cheung 2024-12-13 19:19:42 +00:00
parent cfa04d31dd
commit f647d4d908
5 changed files with 25 additions and 9 deletions

View File

@ -347,6 +347,7 @@ void SharedClassPathEntry::init(bool is_modules_image,
_type = jar_entry;
_timestamp = st.st_mtime;
_from_class_path_attr = cpe->from_class_path_attr();
_is_multi_release = cpe->is_multi_release_jar();
}
_filesize = st.st_size;
_is_module_path = is_module_path;
@ -2680,7 +2681,7 @@ ClassPathEntry* FileMapInfo::get_classpath_entry_for_jvmti(int i, TRAPS) {
jio_snprintf(msg, strlen(path) + 127, "error in finding JAR file %s", path);
THROW_MSG_(vmSymbols::java_io_IOException(), msg, nullptr);
} else {
ent = ClassLoader::create_class_path_entry(THREAD, path, &st, false, false);
ent = ClassLoader::create_class_path_entry(THREAD, path, &st, false, false, scpe->is_multi_release());
if (ent == nullptr) {
char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128);
jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
@ -2715,7 +2716,7 @@ ClassFileStream* FileMapInfo::open_stream_for_jvmti(InstanceKlass* ik, Handle cl
name->utf8_length());
ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
ClassFileStream* cfs;
if (class_loader() != nullptr && !cpe->is_modules_image()) {
if (class_loader() != nullptr && !cpe->is_modules_image() && cpe->is_multi_release_jar()) {
cfs = get_stream_from_class_loader(class_loader, cpe, file_name, CHECK_NULL);
} else {
cfs = cpe->open_stream_for_loader(THREAD, file_name, loader_data);

View File

@ -64,6 +64,7 @@ class SharedClassPathEntry : public MetaspaceObj {
u1 _type;
bool _is_module_path;
bool _from_class_path_attr;
bool _is_multi_release;
time_t _timestamp; // jar timestamp, 0 if is directory, modules image or other
int64_t _filesize; // jar/jimage file size, -1 if is directory, -2 if other
Array<char>* _name;
@ -71,7 +72,7 @@ class SharedClassPathEntry : public MetaspaceObj {
public:
SharedClassPathEntry() : _type(0), _is_module_path(false),
_from_class_path_attr(false), _timestamp(0),
_from_class_path_attr(false), _is_multi_release(false), _timestamp(0),
_filesize(0), _name(nullptr), _manifest(nullptr) {}
static int size() {
static_assert(is_aligned(sizeof(SharedClassPathEntry), wordSize), "must be");
@ -92,6 +93,7 @@ public:
bool is_jar() const { return _type == jar_entry; }
bool is_non_existent() const { return _type == non_existent_entry; }
bool from_class_path_attr() { return _from_class_path_attr; }
bool is_multi_release() { return _is_multi_release; }
time_t timestamp() const { return _timestamp; }
const char* name() const;
const char* manifest() const {

View File

@ -303,10 +303,11 @@ ClassFileStream* ClassPathDirEntry::open_stream(JavaThread* current, const char*
}
ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name,
bool is_boot_append, bool from_class_path_attr) : ClassPathEntry() {
bool is_boot_append, bool from_class_path_attr, bool multi_release) : ClassPathEntry() {
_zip = zip;
_zip_name = copy_path(zip_name);
_from_class_path_attr = from_class_path_attr;
_multi_release = multi_release;
}
ClassPathZipEntry::~ClassPathZipEntry() {
@ -750,7 +751,8 @@ jzfile* ClassLoader::open_zip_file(const char* canonical_path, char** error_msg,
ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current,
const char *path, const struct stat* st,
bool is_boot_append,
bool from_class_path_attr) {
bool from_class_path_attr,
bool is_multi_release) {
ClassPathEntry* new_entry = nullptr;
if ((st->st_mode & S_IFMT) == S_IFREG) {
ResourceMark rm(current);
@ -763,7 +765,7 @@ ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current,
char* error_msg = nullptr;
jzfile* zip = open_zip_file(canonical_path, &error_msg, current);
if (zip != nullptr && error_msg == nullptr) {
new_entry = new ClassPathZipEntry(zip, path, is_boot_append, from_class_path_attr);
new_entry = new ClassPathZipEntry(zip, path, is_boot_append, from_class_path_attr, is_multi_release);
} else {
#if INCLUDE_CDS
ClassLoaderExt::set_has_non_jar_in_classpath();
@ -796,7 +798,7 @@ ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path, bo
jzfile* zip = open_zip_file(canonical_path, &error_msg, thread);
if (zip != nullptr && error_msg == nullptr) {
// create using canonical path
return new ClassPathZipEntry(zip, canonical_path, is_boot_append, false);
return new ClassPathZipEntry(zip, canonical_path, is_boot_append, false, false);
}
}
}

View File

@ -58,6 +58,8 @@ public:
virtual bool is_modules_image() const { return false; }
virtual bool is_jar_file() const { return false; }
virtual bool is_multi_release_jar() const { return false; }
virtual void set_multi_release_jar() {}
// Is this entry created from the "Class-path" attribute from a JAR Manifest?
virtual bool from_class_path_attr() const { return false; }
virtual const char* name() const = 0;
@ -91,11 +93,14 @@ class ClassPathZipEntry: public ClassPathEntry {
jzfile* _zip; // The zip archive
const char* _zip_name; // Name of zip archive
bool _from_class_path_attr; // From the "Class-path" attribute of a jar file
bool _multi_release; // multi-release jar
public:
bool is_jar_file() const { return true; }
bool is_multi_release_jar() const { return _multi_release; }
void set_multi_release_jar() { _multi_release = true; }
bool from_class_path_attr() const { return _from_class_path_attr; }
const char* name() const { return _zip_name; }
ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append, bool from_class_path_attr);
ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append, bool from_class_path_attr, bool multi_release);
virtual ~ClassPathZipEntry();
u1* open_entry(JavaThread* current, const char* name, jint* filesize, bool nul_terminate);
ClassFileStream* open_stream(JavaThread* current, const char* name);
@ -260,7 +265,8 @@ class ClassLoader: AllStatic {
static ClassPathEntry* create_class_path_entry(JavaThread* current,
const char *path, const struct stat* st,
bool is_boot_append,
bool from_class_path_attr);
bool from_class_path_attr,
bool is_multi_release = false);
// Canonicalizes path names, so strcmp will work properly. This is mainly
// to avoid confusing the zip library

View File

@ -244,6 +244,10 @@ void ClassLoaderExt::process_jar_manifest(JavaThread* current, ClassPathEntry* e
vm_exit_during_cds_dumping(err_msg("-Xshare:dump does not support Extension-List in JAR manifest: %s", entry->name()));
}
if (strstr(manifest, "Multi-Release: true") != nullptr) {
entry->set_multi_release_jar();
}
char* cp_attr = get_class_path_attr(entry->name(), manifest, manifest_size);
if (cp_attr != nullptr && strlen(cp_attr) > 0) {
@ -299,6 +303,7 @@ void ClassLoaderExt::process_jar_manifest(JavaThread* current, ClassPathEntry* e
file_start = file_end;
}
}
return;
}
void ClassLoaderExt::setup_search_paths(JavaThread* current) {