8267556: Enhance class paths check during runtime
Reviewed-by: minqi, iklam
This commit is contained in:
parent
8c8422e0f8
commit
4fd2a14997
@ -32,6 +32,7 @@
|
||||
#include "cds/metaspaceShared.hpp"
|
||||
#include "classfile/altHashing.hpp"
|
||||
#include "classfile/classFileStream.hpp"
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/classLoader.inline.hpp"
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/classLoaderExt.hpp"
|
||||
@ -240,6 +241,7 @@ void FileMapHeader::populate(FileMapInfo* mapinfo, size_t core_region_alignment)
|
||||
_verify_local = BytecodeVerificationLocal;
|
||||
_verify_remote = BytecodeVerificationRemote;
|
||||
_has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
|
||||
_has_non_jar_in_classpath = ClassLoaderExt::has_non_jar_in_classpath();
|
||||
_requested_base_address = (char*)SharedBaseAddress;
|
||||
_mapped_base_address = (char*)SharedBaseAddress;
|
||||
_allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
|
||||
@ -293,6 +295,7 @@ void FileMapHeader::print(outputStream* st) {
|
||||
st->print_cr("- verify_local: %d", _verify_local);
|
||||
st->print_cr("- verify_remote: %d", _verify_remote);
|
||||
st->print_cr("- has_platform_or_app_classes: %d", _has_platform_or_app_classes);
|
||||
st->print_cr("- has_non_jar_in_classpath: %d", _has_non_jar_in_classpath);
|
||||
st->print_cr("- requested_base_address: " INTPTR_FORMAT, p2i(_requested_base_address));
|
||||
st->print_cr("- mapped_base_address: " INTPTR_FORMAT, p2i(_mapped_base_address));
|
||||
st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent);
|
||||
@ -717,13 +720,25 @@ int FileMapInfo::num_paths(const char* path) {
|
||||
|
||||
GrowableArray<const char*>* FileMapInfo::create_path_array(const char* paths) {
|
||||
GrowableArray<const char*>* path_array = new GrowableArray<const char*>(10);
|
||||
|
||||
JavaThread* current = JavaThread::current();
|
||||
ClasspathStream cp_stream(paths);
|
||||
bool non_jar_in_cp = header()->has_non_jar_in_classpath();
|
||||
while (cp_stream.has_next()) {
|
||||
const char* path = cp_stream.get_next();
|
||||
struct stat st;
|
||||
if (os::stat(path, &st) == 0) {
|
||||
path_array->append(path);
|
||||
if (!non_jar_in_cp) {
|
||||
struct stat st;
|
||||
if (os::stat(path, &st) == 0) {
|
||||
path_array->append(path);
|
||||
}
|
||||
} else {
|
||||
const char* canonical_path = ClassLoader::get_canonical_path(path, current);
|
||||
if (canonical_path != NULL) {
|
||||
char* error_msg = NULL;
|
||||
jzfile* zip = ClassLoader::open_zip_file(canonical_path, &error_msg, current);
|
||||
if (zip != NULL && error_msg == NULL) {
|
||||
path_array->append(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return path_array;
|
||||
|
@ -203,6 +203,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
|
||||
address _heap_begin; // heap begin at dump time.
|
||||
address _heap_end; // heap end at dump time.
|
||||
bool _base_archive_is_default; // indicates if the base archive is the system default one
|
||||
bool _has_non_jar_in_classpath; // non-jar file entry exists in classpath
|
||||
|
||||
// The following fields are all sanity checks for whether this archive
|
||||
// will function correctly with this JVM and the bootclasspath it's
|
||||
@ -272,6 +273,7 @@ public:
|
||||
char* requested_base_address() const { return _requested_base_address; }
|
||||
char* mapped_base_address() const { return _mapped_base_address; }
|
||||
bool has_platform_or_app_classes() const { return _has_platform_or_app_classes; }
|
||||
bool has_non_jar_in_classpath() const { return _has_non_jar_in_classpath; }
|
||||
size_t ptrmap_size_in_bits() const { return _ptrmap_size_in_bits; }
|
||||
bool compressed_oops() const { return _compressed_oops; }
|
||||
bool compressed_class_pointers() const { return _compressed_class_ptrs; }
|
||||
|
@ -736,6 +736,9 @@ ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current,
|
||||
if (zip != NULL && error_msg == NULL) {
|
||||
new_entry = new ClassPathZipEntry(zip, path, is_boot_append, from_class_path_attr);
|
||||
} else {
|
||||
#if INCLUDE_CDS
|
||||
ClassLoaderExt::set_has_non_jar_in_classpath();
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
log_info(class, path)("opened: %s", path);
|
||||
|
@ -254,9 +254,9 @@ class ClassLoader: AllStatic {
|
||||
static int _libzip_loaded; // used to sync loading zip.
|
||||
static void release_load_zip_library();
|
||||
static inline void load_zip_library_if_needed();
|
||||
static jzfile* open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread);
|
||||
|
||||
public:
|
||||
static jzfile* open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread);
|
||||
static ClassPathEntry* create_class_path_entry(JavaThread* current,
|
||||
const char *path, const struct stat* st,
|
||||
bool is_boot_append,
|
||||
|
@ -56,6 +56,7 @@ jshort ClassLoaderExt::_app_module_paths_start_index = ClassLoaderExt::max_class
|
||||
jshort ClassLoaderExt::_max_used_path_index = 0;
|
||||
bool ClassLoaderExt::_has_app_classes = false;
|
||||
bool ClassLoaderExt::_has_platform_classes = false;
|
||||
bool ClassLoaderExt::_has_non_jar_in_classpath = false;
|
||||
|
||||
void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) {
|
||||
if (UseSharedSpaces) {
|
||||
|
@ -56,6 +56,7 @@ private:
|
||||
|
||||
static bool _has_app_classes;
|
||||
static bool _has_platform_classes;
|
||||
static bool _has_non_jar_in_classpath;
|
||||
|
||||
static char* read_manifest(JavaThread* current, ClassPathEntry* entry, jint *manifest_size, bool clean_text);
|
||||
static ClassPathEntry* find_classpath_entry_from_cache(JavaThread* current, const char* path);
|
||||
@ -107,6 +108,10 @@ public:
|
||||
return _has_app_classes || _has_platform_classes;
|
||||
}
|
||||
|
||||
static bool has_non_jar_in_classpath() {
|
||||
return _has_non_jar_in_classpath;
|
||||
}
|
||||
|
||||
static void record_result(const s2 classpath_index, InstanceKlass* result);
|
||||
static InstanceKlass* load_class(Symbol* h_name, const char* path, TRAPS);
|
||||
static void set_has_app_classes() {
|
||||
@ -115,7 +120,10 @@ public:
|
||||
static void set_has_platform_classes() {
|
||||
_has_platform_classes = true;
|
||||
}
|
||||
#endif
|
||||
static void set_has_non_jar_in_classpath() {
|
||||
_has_non_jar_in_classpath = true;
|
||||
}
|
||||
#endif // INCLUDE_CDS
|
||||
};
|
||||
|
||||
#endif // SHARE_CLASSFILE_CLASSLOADEREXT_HPP
|
||||
|
65
test/hotspot/jtreg/runtime/cds/appcds/NonJarInClasspath.java
Normal file
65
test/hotspot/jtreg/runtime/cds/appcds/NonJarInClasspath.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Non jar file in the classpath will be skipped during dump time and runtime.
|
||||
* @requires vm.cds
|
||||
* @library /test/lib
|
||||
* @compile test-classes/Hello.java
|
||||
* @compile test-classes/HelloMore.java
|
||||
* @run driver NonJarInClasspath
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import jdk.test.lib.cds.CDSTestUtils;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class NonJarInClasspath {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String appJar = JarBuilder.getOrCreateHelloJar();
|
||||
String appJar2 = JarBuilder.build("hellomore", "HelloMore");
|
||||
|
||||
String outDir = CDSTestUtils.getOutputDir();
|
||||
String newFile = "non-exist.jar";
|
||||
String nonJarPath = outDir + File.separator + newFile;
|
||||
String classPath = appJar + File.pathSeparator + nonJarPath + File.pathSeparator + appJar2;
|
||||
File nonJar = new File(outDir, newFile);
|
||||
nonJar.createNewFile();
|
||||
|
||||
TestCommon.testDump(classPath, TestCommon.list("Hello", "HelloMore"));
|
||||
|
||||
TestCommon.run(
|
||||
"-cp", classPath,
|
||||
"-Xlog:class+load",
|
||||
"Hello")
|
||||
.assertNormalExit(out -> {
|
||||
out.shouldContain("Hello source: shared objects file");
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user