mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8194812: Extend class-data sharing to support the module path
8199360: Rework the support for the 'ignored' module options in CDS Reviewed-by: jiangli, lfoltan, iklam, mseledtsov
This commit is contained in:
parent
d187884156
commit
4ef7c919a2
55 changed files with 2009 additions and 349 deletions
|
@ -148,6 +148,8 @@ ClassPathEntry* ClassLoader::_last_append_entry = NULL;
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
ClassPathEntry* ClassLoader::_app_classpath_entries = NULL;
|
ClassPathEntry* ClassLoader::_app_classpath_entries = NULL;
|
||||||
ClassPathEntry* ClassLoader::_last_app_classpath_entry = NULL;
|
ClassPathEntry* ClassLoader::_last_app_classpath_entry = NULL;
|
||||||
|
ClassPathEntry* ClassLoader::_module_path_entries = NULL;
|
||||||
|
ClassPathEntry* ClassLoader::_last_module_path_entry = NULL;
|
||||||
SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
|
SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -721,7 +723,44 @@ void ClassLoader::setup_app_search_path(const char *class_path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
void ClassLoader::add_to_module_path_entries(const char* path,
|
||||||
|
ClassPathEntry* entry) {
|
||||||
|
assert(entry != NULL, "ClassPathEntry should not be NULL");
|
||||||
|
assert(DumpSharedSpaces, "dump time only");
|
||||||
|
|
||||||
|
// The entry does not exist, add to the list
|
||||||
|
if (_module_path_entries == NULL) {
|
||||||
|
assert(_last_module_path_entry == NULL, "Sanity");
|
||||||
|
_module_path_entries = _last_module_path_entry = entry;
|
||||||
|
} else {
|
||||||
|
_last_module_path_entry->set_next(entry);
|
||||||
|
_last_module_path_entry = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a module path to the _module_path_entries list.
|
||||||
|
void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
|
||||||
|
assert(DumpSharedSpaces, "dump time only");
|
||||||
|
struct stat st;
|
||||||
|
int ret = os::stat(path, &st);
|
||||||
|
assert(ret == 0, "module path must exist");
|
||||||
|
// File or directory found
|
||||||
|
ClassPathEntry* new_entry = NULL;
|
||||||
|
new_entry = create_class_path_entry(path, &st, true /* throw_exception */,
|
||||||
|
false /*is_boot_append */, CHECK);
|
||||||
|
if (new_entry == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_to_module_path_entries(path, new_entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassLoader::setup_module_search_path(const char* path, TRAPS) {
|
||||||
|
check_shared_classpath(path);
|
||||||
|
update_module_path_entry_list(path, THREAD);
|
||||||
|
}
|
||||||
|
#endif // INCLUDE_CDS
|
||||||
|
|
||||||
// Construct the array of module/path pairs as specified to --patch-module
|
// Construct the array of module/path pairs as specified to --patch-module
|
||||||
// for the boot loader to search ahead of the jimage, if the class being
|
// for the boot loader to search ahead of the jimage, if the class being
|
||||||
|
@ -1512,7 +1551,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
|
||||||
}
|
}
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
static char* skip_uri_protocol(char* source) {
|
char* ClassLoader::skip_uri_protocol(char* source) {
|
||||||
if (strncmp(source, "file:", 5) == 0) {
|
if (strncmp(source, "file:", 5) == 0) {
|
||||||
// file: protocol path could start with file:/ or file:///
|
// file: protocol path could start with file:/ or file:///
|
||||||
// locate the char after all the forward slashes
|
// locate the char after all the forward slashes
|
||||||
|
@ -1533,7 +1572,7 @@ static char* skip_uri_protocol(char* source) {
|
||||||
|
|
||||||
// Record the shared classpath index and loader type for classes loaded
|
// Record the shared classpath index and loader type for classes loaded
|
||||||
// by the builtin loaders at dump time.
|
// by the builtin loaders at dump time.
|
||||||
void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream) {
|
void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS) {
|
||||||
assert(DumpSharedSpaces, "sanity");
|
assert(DumpSharedSpaces, "sanity");
|
||||||
assert(stream != NULL, "sanity");
|
assert(stream != NULL, "sanity");
|
||||||
|
|
||||||
|
@ -1542,9 +1581,10 @@ void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oop loader = ik->class_loader();
|
||||||
char* src = (char*)stream->source();
|
char* src = (char*)stream->source();
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
if (ik->class_loader() == NULL) {
|
if (loader == NULL) {
|
||||||
// JFR classes
|
// JFR classes
|
||||||
ik->set_shared_classpath_index(0);
|
ik->set_shared_classpath_index(0);
|
||||||
ik->set_class_loader_type(ClassLoader::BOOT_LOADER);
|
ik->set_class_loader_type(ClassLoader::BOOT_LOADER);
|
||||||
|
@ -1554,41 +1594,84 @@ void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream
|
||||||
|
|
||||||
assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build");
|
assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build");
|
||||||
|
|
||||||
ModuleEntry* module = ik->module();
|
ResourceMark rm(THREAD);
|
||||||
int classpath_index = -1;
|
int classpath_index = -1;
|
||||||
ResourceMark rm;
|
PackageEntry* pkg_entry = ik->package();
|
||||||
char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN);
|
|
||||||
|
|
||||||
// save the path from the file: protocol or the module name from the jrt: protocol
|
if (FileMapInfo::get_number_of_shared_paths() > 0) {
|
||||||
// if no protocol prefix is found, path is the same as stream->source()
|
char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN);
|
||||||
char* path = skip_uri_protocol(src);
|
|
||||||
for (int i = 0; i < FileMapInfo::get_number_of_share_classpaths(); i++) {
|
// save the path from the file: protocol or the module name from the jrt: protocol
|
||||||
SharedClassPathEntry* ent = FileMapInfo::shared_classpath(i);
|
// if no protocol prefix is found, path is the same as stream->source()
|
||||||
if (get_canonical_path(ent->name(), canonical_path, JVM_MAXPATHLEN)) {
|
char* path = skip_uri_protocol(src);
|
||||||
// If the path (from the class stream srouce) is the same as the shared
|
for (int i = 0; i < FileMapInfo::get_number_of_shared_paths(); i++) {
|
||||||
// class path, then we have a match. For classes from module image loaded by the
|
SharedClassPathEntry* ent = FileMapInfo::shared_path(i);
|
||||||
// PlatformClassLoader, the stream->source() is not the name of the module image.
|
if (get_canonical_path(ent->name(), canonical_path, JVM_MAXPATHLEN)) {
|
||||||
// Need to look for 'jrt:' explicitly.
|
// If the path (from the class stream source) is the same as the shared
|
||||||
if (strcmp(canonical_path, os::native_path((char*)path)) == 0 ||
|
// class or module path, then we have a match.
|
||||||
(i == 0 && string_starts_with(src, "jrt:"))) {
|
if (strcmp(canonical_path, os::native_path((char*)path)) == 0) {
|
||||||
classpath_index = i;
|
// NULL pkg_entry and pkg_entry in an unnamed module implies the class
|
||||||
break;
|
// is from the -cp or boot loader append path which consists of -Xbootclasspath/a
|
||||||
|
// and jvmti appended entries.
|
||||||
|
if ((pkg_entry == NULL) || (pkg_entry->in_unnamed_module())) {
|
||||||
|
// Ensure the index is within the -cp range before assigning
|
||||||
|
// to the classpath_index.
|
||||||
|
if (SystemDictionary::is_system_class_loader(loader) &&
|
||||||
|
(i >= ClassLoaderExt::app_class_paths_start_index()) &&
|
||||||
|
(i < ClassLoaderExt::app_module_paths_start_index())) {
|
||||||
|
classpath_index = i;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if ((i >= 1) &&
|
||||||
|
(i < ClassLoaderExt::app_class_paths_start_index())) {
|
||||||
|
// The class must be from boot loader append path which consists of
|
||||||
|
// -Xbootclasspath/a and jvmti appended entries.
|
||||||
|
assert(loader == NULL, "sanity");
|
||||||
|
classpath_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// A class from a named module from the --module-path. Ensure the index is
|
||||||
|
// within the --module-path range before assigning to the classpath_index.
|
||||||
|
if ((pkg_entry != NULL) && !(pkg_entry->in_unnamed_module()) && (i > 0)) {
|
||||||
|
if (i >= ClassLoaderExt::app_module_paths_start_index() &&
|
||||||
|
i < FileMapInfo::get_number_of_shared_paths()) {
|
||||||
|
classpath_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for index 0 and the stream->source() is the modules image or has the jrt: protocol.
|
||||||
|
// The class must be from the runtime modules image.
|
||||||
|
if (i == 0 && (is_modules_image(src) || string_starts_with(src, "jrt:"))) {
|
||||||
|
classpath_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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
|
// No path entry found for this class. Must be a shared class loaded by the
|
||||||
// user defined classloader.
|
// user defined classloader.
|
||||||
assert(ik->shared_classpath_index() < 0, "Sanity");
|
if (classpath_index < 0) {
|
||||||
return;
|
assert(ik->shared_classpath_index() < 0, "Sanity");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The shared path table is set up after module system initialization.
|
||||||
|
// The path table contains no entry before that. Any classes loaded prior
|
||||||
|
// to the setup of the shared path table must be from the modules image.
|
||||||
|
assert(is_modules_image(src), "stream must be from modules image");
|
||||||
|
assert(FileMapInfo::get_number_of_shared_paths() == 0, "shared path table must not have been setup");
|
||||||
|
classpath_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* const class_name = ik->name()->as_C_string();
|
const char* const class_name = ik->name()->as_C_string();
|
||||||
const char* const file_name = file_name_for_class_name(class_name,
|
const char* const file_name = file_name_for_class_name(class_name,
|
||||||
ik->name()->utf8_length());
|
ik->name()->utf8_length());
|
||||||
assert(file_name != NULL, "invariant");
|
assert(file_name != NULL, "invariant");
|
||||||
Thread* THREAD = Thread::current();
|
|
||||||
ClassLoaderExt::Context context(class_name, file_name, CATCH);
|
ClassLoaderExt::Context context(class_name, file_name, CATCH);
|
||||||
context.record_result(ik->name(), classpath_index, ik, THREAD);
|
context.record_result(ik->name(), classpath_index, ik, THREAD);
|
||||||
}
|
}
|
||||||
|
@ -1673,6 +1756,13 @@ void ClassLoader::initialize_shared_path() {
|
||||||
_shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
|
_shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClassLoader::initialize_module_path(TRAPS) {
|
||||||
|
if (DumpSharedSpaces) {
|
||||||
|
ClassLoaderExt::setup_module_paths(THREAD);
|
||||||
|
FileMapInfo::allocate_shared_path_table();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
jlong ClassLoader::classloader_time_ms() {
|
jlong ClassLoader::classloader_time_ms() {
|
||||||
|
|
|
@ -238,12 +238,18 @@ class ClassLoader: AllStatic {
|
||||||
|
|
||||||
CDS_ONLY(static ClassPathEntry* _app_classpath_entries;)
|
CDS_ONLY(static ClassPathEntry* _app_classpath_entries;)
|
||||||
CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;)
|
CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;)
|
||||||
CDS_ONLY(static void setup_app_search_path(const char *class_path);)
|
CDS_ONLY(static ClassPathEntry* _module_path_entries;)
|
||||||
|
CDS_ONLY(static ClassPathEntry* _last_module_path_entry;)
|
||||||
|
CDS_ONLY(static void setup_app_search_path(const char* class_path);)
|
||||||
|
CDS_ONLY(static void setup_module_search_path(const char* path, TRAPS);)
|
||||||
static void add_to_app_classpath_entries(const char* path,
|
static void add_to_app_classpath_entries(const char* path,
|
||||||
ClassPathEntry* entry,
|
ClassPathEntry* entry,
|
||||||
bool check_for_duplicates);
|
bool check_for_duplicates);
|
||||||
|
CDS_ONLY(static void add_to_module_path_entries(const char* path,
|
||||||
|
ClassPathEntry* entry);)
|
||||||
public:
|
public:
|
||||||
CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})
|
CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})
|
||||||
|
CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;})
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Initialization:
|
// Initialization:
|
||||||
|
@ -286,6 +292,7 @@ class ClassLoader: AllStatic {
|
||||||
bool check_for_duplicates,
|
bool check_for_duplicates,
|
||||||
bool is_boot_append,
|
bool is_boot_append,
|
||||||
bool throw_exception=true);
|
bool throw_exception=true);
|
||||||
|
CDS_ONLY(static void update_module_path_entry_list(const char *path, TRAPS);)
|
||||||
static void print_bootclasspath();
|
static void print_bootclasspath();
|
||||||
|
|
||||||
// Timing
|
// Timing
|
||||||
|
@ -382,6 +389,7 @@ class ClassLoader: AllStatic {
|
||||||
static void initialize();
|
static void initialize();
|
||||||
static void classLoader_init2(TRAPS);
|
static void classLoader_init2(TRAPS);
|
||||||
CDS_ONLY(static void initialize_shared_path();)
|
CDS_ONLY(static void initialize_shared_path();)
|
||||||
|
CDS_ONLY(static void initialize_module_path(TRAPS);)
|
||||||
|
|
||||||
static int compute_Object_vtable();
|
static int compute_Object_vtable();
|
||||||
|
|
||||||
|
@ -402,14 +410,28 @@ class ClassLoader: AllStatic {
|
||||||
// entries during shared classpath setup time.
|
// entries during shared classpath setup time.
|
||||||
static int num_app_classpath_entries();
|
static int num_app_classpath_entries();
|
||||||
|
|
||||||
|
// Helper function used by CDS code to get the number of module path
|
||||||
|
// entries during shared classpath setup time.
|
||||||
|
static int num_module_path_entries() {
|
||||||
|
assert(DumpSharedSpaces, "Should only be called at CDS dump time");
|
||||||
|
int num_entries = 0;
|
||||||
|
ClassPathEntry* e= ClassLoader::_module_path_entries;
|
||||||
|
while (e != NULL) {
|
||||||
|
num_entries ++;
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
return num_entries;
|
||||||
|
}
|
||||||
static void check_shared_classpath(const char *path);
|
static void check_shared_classpath(const char *path);
|
||||||
static void finalize_shared_paths_misc_info();
|
static void finalize_shared_paths_misc_info();
|
||||||
static int get_shared_paths_misc_info_size();
|
static int get_shared_paths_misc_info_size();
|
||||||
static void* get_shared_paths_misc_info();
|
static void* get_shared_paths_misc_info();
|
||||||
static bool check_shared_paths_misc_info(void* info, int size);
|
static bool check_shared_paths_misc_info(void* info, int size);
|
||||||
|
static int get_module_paths_misc_info_size();
|
||||||
|
static void* get_module_paths_misc_info();
|
||||||
static void exit_with_path_failure(const char* error, const char* message);
|
static void exit_with_path_failure(const char* error, const char* message);
|
||||||
|
static char* skip_uri_protocol(char* source);
|
||||||
static void record_result(InstanceKlass* ik, const ClassFileStream* stream);
|
static void record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS);
|
||||||
#endif
|
#endif
|
||||||
static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name,
|
static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name,
|
||||||
const char* file_name, jlong &size);
|
const char* file_name, jlong &size);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "classfile/classLoaderExt.hpp"
|
#include "classfile/classLoaderExt.hpp"
|
||||||
#include "classfile/classLoaderData.inline.hpp"
|
#include "classfile/classLoaderData.inline.hpp"
|
||||||
#include "classfile/klassFactory.hpp"
|
#include "classfile/klassFactory.hpp"
|
||||||
|
#include "classfile/modules.hpp"
|
||||||
#include "classfile/sharedClassUtil.hpp"
|
#include "classfile/sharedClassUtil.hpp"
|
||||||
#include "classfile/sharedPathsMiscInfo.hpp"
|
#include "classfile/sharedPathsMiscInfo.hpp"
|
||||||
#include "classfile/systemDictionaryShared.hpp"
|
#include "classfile/systemDictionaryShared.hpp"
|
||||||
|
@ -41,19 +42,21 @@
|
||||||
#include "oops/oop.inline.hpp"
|
#include "oops/oop.inline.hpp"
|
||||||
#include "oops/symbol.hpp"
|
#include "oops/symbol.hpp"
|
||||||
#include "runtime/arguments.hpp"
|
#include "runtime/arguments.hpp"
|
||||||
|
#include "runtime/handles.inline.hpp"
|
||||||
#include "runtime/java.hpp"
|
#include "runtime/java.hpp"
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
#include "services/threadService.hpp"
|
#include "services/threadService.hpp"
|
||||||
#include "utilities/stringUtils.hpp"
|
#include "utilities/stringUtils.hpp"
|
||||||
|
|
||||||
jshort ClassLoaderExt::_app_paths_start_index = ClassLoaderExt::max_classpath_index;
|
jshort ClassLoaderExt::_app_class_paths_start_index = ClassLoaderExt::max_classpath_index;
|
||||||
|
jshort ClassLoaderExt::_app_module_paths_start_index = ClassLoaderExt::max_classpath_index;
|
||||||
bool ClassLoaderExt::_has_app_classes = false;
|
bool ClassLoaderExt::_has_app_classes = false;
|
||||||
bool ClassLoaderExt::_has_platform_classes = false;
|
bool ClassLoaderExt::_has_platform_classes = false;
|
||||||
|
|
||||||
void ClassLoaderExt::setup_app_search_path() {
|
void ClassLoaderExt::setup_app_search_path() {
|
||||||
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
|
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
|
||||||
_app_paths_start_index = ClassLoader::num_boot_classpath_entries();
|
_app_class_paths_start_index = ClassLoader::num_boot_classpath_entries();
|
||||||
char* app_class_path = os::strdup(Arguments::get_appclasspath());
|
char* app_class_path = os::strdup(Arguments::get_appclasspath());
|
||||||
|
|
||||||
if (strcmp(app_class_path, ".") == 0) {
|
if (strcmp(app_class_path, ".") == 0) {
|
||||||
|
@ -68,6 +71,29 @@ void ClassLoaderExt::setup_app_search_path() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClassLoaderExt::process_module_table(ModuleEntryTable* met, TRAPS) {
|
||||||
|
ResourceMark rm;
|
||||||
|
for (int i = 0; i < met->table_size(); i++) {
|
||||||
|
for (ModuleEntry* m = met->bucket(i); m != NULL;) {
|
||||||
|
char* path = m->location()->as_C_string();
|
||||||
|
if (strncmp(path, "file:", 5) == 0 && ClassLoader::string_ends_with(path, ".jar")) {
|
||||||
|
m->print();
|
||||||
|
path = ClassLoader::skip_uri_protocol(path);
|
||||||
|
ClassLoader::setup_module_search_path(path, THREAD);
|
||||||
|
}
|
||||||
|
m = m->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ClassLoaderExt::setup_module_search_path(TRAPS) {
|
||||||
|
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
|
||||||
|
_app_module_paths_start_index = ClassLoader::num_boot_classpath_entries() +
|
||||||
|
ClassLoader::num_app_classpath_entries();
|
||||||
|
Handle system_class_loader (THREAD, SystemDictionary::java_system_loader());
|
||||||
|
ModuleEntryTable* met = Modules::get_module_entry_table(system_class_loader);
|
||||||
|
process_module_table(met, THREAD);
|
||||||
|
}
|
||||||
|
|
||||||
char* ClassLoaderExt::read_manifest(ClassPathEntry* entry, jint *manifest_size, bool clean_text, TRAPS) {
|
char* ClassLoaderExt::read_manifest(ClassPathEntry* entry, jint *manifest_size, bool clean_text, TRAPS) {
|
||||||
const char* name = "META-INF/MANIFEST.MF";
|
const char* name = "META-INF/MANIFEST.MF";
|
||||||
char* manifest;
|
char* manifest;
|
||||||
|
@ -195,6 +221,12 @@ void ClassLoaderExt::setup_search_paths() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClassLoaderExt::setup_module_paths(TRAPS) {
|
||||||
|
if (UseAppCDS) {
|
||||||
|
ClassLoaderExt::setup_module_search_path(THREAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Thread* ClassLoaderExt::Context::_dump_thread = NULL;
|
Thread* ClassLoaderExt::Context::_dump_thread = NULL;
|
||||||
|
|
||||||
void ClassLoaderExt::record_result(ClassLoaderExt::Context *context,
|
void ClassLoaderExt::record_result(ClassLoaderExt::Context *context,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#define SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
|
#define SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
|
||||||
|
|
||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
|
#include "classfile/moduleEntry.hpp"
|
||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
|
|
||||||
CDS_ONLY(class SharedPathsMiscInfoExt;)
|
CDS_ONLY(class SharedPathsMiscInfoExt;)
|
||||||
|
@ -59,14 +60,14 @@ public:
|
||||||
_file_name = file_name;
|
_file_name = file_name;
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
if (!DumpSharedSpaces && !UseSharedSpaces) {
|
if (!DumpSharedSpaces && !UseSharedSpaces) {
|
||||||
// Must not modify _app_paths_start_index if we're not using CDS.
|
// Must not modify _app_class_paths_start_index if we're not using CDS.
|
||||||
assert(_app_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
|
assert(_app_class_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool should_verify(int classpath_index) {
|
bool should_verify(int classpath_index) {
|
||||||
CDS_ONLY(return (classpath_index >= _app_paths_start_index);)
|
CDS_ONLY(return (classpath_index >= _app_class_paths_start_index);)
|
||||||
NOT_CDS(return false;)
|
NOT_CDS(return false;)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +83,8 @@ public:
|
||||||
~Context() {
|
~Context() {
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
if (!DumpSharedSpaces && !UseSharedSpaces) {
|
if (!DumpSharedSpaces && !UseSharedSpaces) {
|
||||||
// Must not modify app_paths_start_index if we're not using CDS.
|
// Must not modify app_class_paths_start_index if we're not using CDS.
|
||||||
assert(_app_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
|
assert(_app_class_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -93,10 +94,16 @@ private:
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size);
|
static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size);
|
||||||
static void setup_app_search_path(); // Only when -Xshare:dump
|
static void setup_app_search_path(); // Only when -Xshare:dump
|
||||||
|
static void process_module_table(ModuleEntryTable* met, TRAPS);
|
||||||
|
static void setup_module_search_path(TRAPS);
|
||||||
static SharedPathsMiscInfoExt* shared_paths_misc_info() {
|
static SharedPathsMiscInfoExt* shared_paths_misc_info() {
|
||||||
return (SharedPathsMiscInfoExt*)_shared_paths_misc_info;
|
return (SharedPathsMiscInfoExt*)_shared_paths_misc_info;
|
||||||
}
|
}
|
||||||
static jshort _app_paths_start_index; // index of first app JAR in shared classpath entry table
|
// index of first app JAR in shared classpath entry table
|
||||||
|
static jshort _app_class_paths_start_index;
|
||||||
|
// index of first modular JAR in shared modulepath entry table
|
||||||
|
static jshort _app_module_paths_start_index;
|
||||||
|
|
||||||
static bool _has_app_classes;
|
static bool _has_app_classes;
|
||||||
static bool _has_platform_classes;
|
static bool _has_platform_classes;
|
||||||
#endif
|
#endif
|
||||||
|
@ -116,6 +123,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_search_paths() NOT_CDS_RETURN;
|
static void setup_search_paths() NOT_CDS_RETURN;
|
||||||
|
static void setup_module_paths(TRAPS) NOT_CDS_RETURN;
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
private:
|
private:
|
||||||
|
@ -137,14 +145,20 @@ public:
|
||||||
|
|
||||||
static void finalize_shared_paths_misc_info();
|
static void finalize_shared_paths_misc_info();
|
||||||
|
|
||||||
static jshort app_paths_start_index() { return _app_paths_start_index; }
|
static jshort app_class_paths_start_index() { return _app_class_paths_start_index; }
|
||||||
|
|
||||||
|
static jshort app_module_paths_start_index() { return _app_module_paths_start_index; }
|
||||||
|
|
||||||
static void init_paths_start_index(jshort app_start) {
|
static void init_paths_start_index(jshort app_start) {
|
||||||
_app_paths_start_index = app_start;
|
_app_class_paths_start_index = app_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_app_module_paths_start_index(jshort module_start) {
|
||||||
|
_app_module_paths_start_index = module_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_boot_classpath(int classpath_index) {
|
static bool is_boot_classpath(int classpath_index) {
|
||||||
return classpath_index < _app_paths_start_index;
|
return classpath_index < _app_class_paths_start_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool has_platform_or_app_classes() {
|
static bool has_platform_or_app_classes() {
|
||||||
|
|
|
@ -84,7 +84,7 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SharedClassPathEntry* ent =
|
SharedClassPathEntry* ent =
|
||||||
(SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
|
(SharedClassPathEntry*)FileMapInfo::shared_path(path_index);
|
||||||
pathname = ent == NULL ? NULL : ent->name();
|
pathname = ent == NULL ? NULL : ent->name();
|
||||||
}
|
}
|
||||||
ClassFileStream* stream = new ClassFileStream(ptr,
|
ClassFileStream* stream = new ClassFileStream(ptr,
|
||||||
|
@ -232,7 +232,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
if (DumpSharedSpaces) {
|
if (DumpSharedSpaces) {
|
||||||
ClassLoader::record_result(result, stream);
|
ClassLoader::record_result(result, stream, THREAD);
|
||||||
#if INCLUDE_JVMTI
|
#if INCLUDE_JVMTI
|
||||||
assert(cached_class_file == NULL, "Sanity");
|
assert(cached_class_file == NULL, "Sanity");
|
||||||
// Archive the class stream data into the optional data section
|
// Archive the class stream data into the optional data section
|
||||||
|
|
|
@ -85,7 +85,7 @@ static const char* get_module_version(jstring version) {
|
||||||
return java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(version));
|
return java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(version));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ModuleEntryTable* get_module_entry_table(Handle h_loader) {
|
ModuleEntryTable* Modules::get_module_entry_table(Handle h_loader) {
|
||||||
// This code can be called during start-up, before the classLoader's classLoader data got
|
// This code can be called during start-up, before the classLoader's classLoader data got
|
||||||
// created. So, call register_loader() to make sure the classLoader data gets created.
|
// created. So, call register_loader() to make sure the classLoader data gets created.
|
||||||
ClassLoaderData *loader_cld = SystemDictionary::register_loader(h_loader);
|
ClassLoaderData *loader_cld = SystemDictionary::register_loader(h_loader);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
#include "memory/allocation.hpp"
|
#include "memory/allocation.hpp"
|
||||||
#include "runtime/handles.hpp"
|
#include "runtime/handles.hpp"
|
||||||
|
|
||||||
|
class ModuleEntryTable;
|
||||||
class Symbol;
|
class Symbol;
|
||||||
|
|
||||||
class Modules : AllStatic {
|
class Modules : AllStatic {
|
||||||
|
@ -122,6 +123,7 @@ public:
|
||||||
|
|
||||||
// Return TRUE iff package is defined by loader
|
// Return TRUE iff package is defined by loader
|
||||||
static bool is_package_defined(Symbol* package_name, Handle h_loader, TRAPS);
|
static bool is_package_defined(Symbol* package_name, Handle h_loader, TRAPS);
|
||||||
|
static ModuleEntryTable* get_module_entry_table(Handle h_loader);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_CLASSFILE_MODULES_HPP
|
#endif // SHARE_VM_CLASSFILE_MODULES_HPP
|
||||||
|
|
|
@ -93,6 +93,9 @@ void SharedPathsMiscInfoExt::print_path(outputStream* out, int type, const char*
|
||||||
case APP:
|
case APP:
|
||||||
ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
|
ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
|
||||||
break;
|
break;
|
||||||
|
case MODULE:
|
||||||
|
ClassLoader::trace_class_path("Checking module path: ", path);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
SharedPathsMiscInfo::print_path(out, type, path);
|
SharedPathsMiscInfo::print_path(out, type, path);
|
||||||
}
|
}
|
||||||
|
@ -167,12 +170,13 @@ void SharedClassUtil::update_shared_classpath(ClassPathEntry *cpe, SharedClassPa
|
||||||
|
|
||||||
void SharedClassUtil::initialize(TRAPS) {
|
void SharedClassUtil::initialize(TRAPS) {
|
||||||
if (UseSharedSpaces) {
|
if (UseSharedSpaces) {
|
||||||
int size = FileMapInfo::get_number_of_share_classpaths();
|
int size = FileMapInfo::get_number_of_shared_paths();
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
|
SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
|
||||||
if (!DumpSharedSpaces) {
|
if (!DumpSharedSpaces) {
|
||||||
FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
|
FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
|
||||||
ClassLoaderExt::init_paths_start_index(header->_app_paths_start_index);
|
ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
|
||||||
|
ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +212,7 @@ void SharedClassUtil::read_extra_data(const char* filename, TRAPS) {
|
||||||
bool SharedClassUtil::is_classpath_entry_signed(int classpath_index) {
|
bool SharedClassUtil::is_classpath_entry_signed(int classpath_index) {
|
||||||
assert(classpath_index >= 0, "Sanity");
|
assert(classpath_index >= 0, "Sanity");
|
||||||
SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)
|
SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)
|
||||||
FileMapInfo::shared_classpath(classpath_index);
|
FileMapInfo::shared_path(classpath_index);
|
||||||
return ent->_is_signed;
|
return ent->_is_signed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +220,8 @@ void FileMapHeaderExt::populate(FileMapInfo* mapinfo, size_t alignment) {
|
||||||
FileMapInfo::FileMapHeader::populate(mapinfo, alignment);
|
FileMapInfo::FileMapHeader::populate(mapinfo, alignment);
|
||||||
|
|
||||||
ClassLoaderExt::finalize_shared_paths_misc_info();
|
ClassLoaderExt::finalize_shared_paths_misc_info();
|
||||||
_app_paths_start_index = ClassLoaderExt::app_paths_start_index();
|
_app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
|
||||||
|
_app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
|
||||||
|
|
||||||
_verify_local = BytecodeVerificationLocal;
|
_verify_local = BytecodeVerificationLocal;
|
||||||
_verify_remote = BytecodeVerificationRemote;
|
_verify_remote = BytecodeVerificationRemote;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -34,10 +34,11 @@
|
||||||
|
|
||||||
class FileMapHeaderExt: public FileMapInfo::FileMapHeader {
|
class FileMapHeaderExt: public FileMapInfo::FileMapHeader {
|
||||||
public:
|
public:
|
||||||
jshort _app_paths_start_index; // Index of first app classpath entry
|
jshort _app_class_paths_start_index; // Index of first app classpath entry
|
||||||
bool _verify_local; // BytecodeVerificationLocal setting
|
jshort _app_module_paths_start_index; // Index of first module path entry
|
||||||
bool _verify_remote; // BytecodeVerificationRemote setting
|
bool _verify_local; // BytecodeVerificationLocal setting
|
||||||
bool _has_platform_or_app_classes; // Archive contains app classes
|
bool _verify_remote; // BytecodeVerificationRemote setting
|
||||||
|
bool _has_platform_or_app_classes; // Archive contains app classes
|
||||||
|
|
||||||
FileMapHeaderExt() {
|
FileMapHeaderExt() {
|
||||||
_has_platform_or_app_classes = true;
|
_has_platform_or_app_classes = true;
|
||||||
|
@ -56,12 +57,14 @@ private:
|
||||||
int _app_offset;
|
int _app_offset;
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
APP = 5
|
APP = 5,
|
||||||
|
MODULE = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual const char* type_name(int type) {
|
virtual const char* type_name(int type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case APP: return "APP";
|
case APP: return "APP";
|
||||||
|
case MODULE: return "MODULE";
|
||||||
default: return SharedPathsMiscInfo::type_name(type);
|
default: return SharedPathsMiscInfo::type_name(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1217,7 +1217,7 @@ bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SharedClassPathEntry* ent =
|
SharedClassPathEntry* ent =
|
||||||
(SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
|
(SharedClassPathEntry*)FileMapInfo::shared_path(path_index);
|
||||||
if (!Universe::is_module_initialized()) {
|
if (!Universe::is_module_initialized()) {
|
||||||
assert(ent != NULL && ent->is_modules_image(),
|
assert(ent != NULL && ent->is_modules_image(),
|
||||||
"Loading non-bootstrap classes before the module system is initialized");
|
"Loading non-bootstrap classes before the module system is initialized");
|
||||||
|
|
|
@ -92,7 +92,7 @@ Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TR
|
||||||
Handle empty;
|
Handle empty;
|
||||||
Handle manifest ;
|
Handle manifest ;
|
||||||
if (shared_jar_manifest(shared_path_index) == NULL) {
|
if (shared_jar_manifest(shared_path_index) == NULL) {
|
||||||
SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)FileMapInfo::shared_classpath(shared_path_index);
|
SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)FileMapInfo::shared_path(shared_path_index);
|
||||||
long size = ent->manifest_size();
|
long size = ent->manifest_size();
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
return empty; // No manifest - return NULL handle
|
return empty; // No manifest - return NULL handle
|
||||||
|
@ -138,7 +138,7 @@ Handle SystemDictionaryShared::get_shared_jar_url(int shared_path_index, TRAPS)
|
||||||
Handle url_h;
|
Handle url_h;
|
||||||
if (shared_jar_url(shared_path_index) == NULL) {
|
if (shared_jar_url(shared_path_index) == NULL) {
|
||||||
JavaValue result(T_OBJECT);
|
JavaValue result(T_OBJECT);
|
||||||
const char* path = FileMapInfo::shared_classpath_name(shared_path_index);
|
const char* path = FileMapInfo::shared_path_name(shared_path_index);
|
||||||
Handle path_string = java_lang_String::create_from_str(path, CHECK_(url_h));
|
Handle path_string = java_lang_String::create_from_str(path, CHECK_(url_h));
|
||||||
Klass* classLoaders_klass =
|
Klass* classLoaders_klass =
|
||||||
SystemDictionary::jdk_internal_loader_ClassLoaders_klass();
|
SystemDictionary::jdk_internal_loader_ClassLoaders_klass();
|
||||||
|
@ -304,7 +304,7 @@ Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceK
|
||||||
int index = ik->shared_classpath_index();
|
int index = ik->shared_classpath_index();
|
||||||
assert(index >= 0, "Sanity");
|
assert(index >= 0, "Sanity");
|
||||||
SharedClassPathEntryExt* ent =
|
SharedClassPathEntryExt* ent =
|
||||||
(SharedClassPathEntryExt*)FileMapInfo::shared_classpath(index);
|
(SharedClassPathEntryExt*)FileMapInfo::shared_path(index);
|
||||||
Symbol* class_name = ik->name();
|
Symbol* class_name = ik->name();
|
||||||
|
|
||||||
if (ent->is_modules_image()) {
|
if (ent->is_modules_image()) {
|
||||||
|
@ -328,13 +328,13 @@ Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceK
|
||||||
// For shared app/platform classes originated from JAR files on the class path:
|
// For shared app/platform classes originated from JAR files on the class path:
|
||||||
// Each of the 3 SystemDictionaryShared::_shared_xxx arrays has the same length
|
// Each of the 3 SystemDictionaryShared::_shared_xxx arrays has the same length
|
||||||
// as the shared classpath table in the shared archive (see
|
// as the shared classpath table in the shared archive (see
|
||||||
// FileMap::_classpath_entry_table in filemap.hpp for details).
|
// FileMap::_shared_path_table in filemap.hpp for details).
|
||||||
//
|
//
|
||||||
// If a shared InstanceKlass k is loaded from the class path, let
|
// If a shared InstanceKlass k is loaded from the class path, let
|
||||||
//
|
//
|
||||||
// index = k->shared_classpath_index():
|
// index = k->shared_classpath_index():
|
||||||
//
|
//
|
||||||
// FileMap::_classpath_entry_table[index] identifies the JAR file that contains k.
|
// FileMap::_shared_path_table[index] identifies the JAR file that contains k.
|
||||||
//
|
//
|
||||||
// k's protection domain is:
|
// k's protection domain is:
|
||||||
//
|
//
|
||||||
|
@ -358,9 +358,7 @@ Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceK
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently AppCDS only archives classes from the run-time image, the
|
// Currently AppCDS only archives classes from the run-time image, the
|
||||||
// -Xbootclasspath/a path, and the class path. The following rules need to be
|
// -Xbootclasspath/a path, the class path, and the module path.
|
||||||
// revised when AppCDS is changed to archive classes from other code sources
|
|
||||||
// in the future, for example the module path (specified by -p).
|
|
||||||
//
|
//
|
||||||
// Check if a shared class can be loaded by the specific classloader. Following
|
// Check if a shared class can be loaded by the specific classloader. Following
|
||||||
// are the "visible" archived classes for different classloaders.
|
// are the "visible" archived classes for different classloaders.
|
||||||
|
@ -368,10 +366,10 @@ Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceK
|
||||||
// NULL classloader:
|
// NULL classloader:
|
||||||
// - see SystemDictionary::is_shared_class_visible()
|
// - see SystemDictionary::is_shared_class_visible()
|
||||||
// Platform classloader:
|
// Platform classloader:
|
||||||
// - Module class from "modules" jimage. ModuleEntry must be defined in the
|
// - Module class from runtime image. ModuleEntry must be defined in the
|
||||||
// classloader.
|
// classloader.
|
||||||
// App Classloader:
|
// App classloader:
|
||||||
// - Module class from "modules" jimage. ModuleEntry must be defined in the
|
// - Module Class from runtime image and module path. ModuleEntry must be defined in the
|
||||||
// classloader.
|
// classloader.
|
||||||
// - Class from -cp. The class must have no PackageEntry defined in any of the
|
// - Class from -cp. The class must have no PackageEntry defined in any of the
|
||||||
// boot/platform/app classloader, or must be in the unnamed module defined in the
|
// boot/platform/app classloader, or must be in the unnamed module defined in the
|
||||||
|
@ -386,10 +384,11 @@ bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
assert(class_loader.not_null(), "Class loader should not be NULL");
|
assert(class_loader.not_null(), "Class loader should not be NULL");
|
||||||
assert(Universe::is_module_initialized(), "Module system is not initialized");
|
assert(Universe::is_module_initialized(), "Module system is not initialized");
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
|
||||||
int path_index = ik->shared_classpath_index();
|
int path_index = ik->shared_classpath_index();
|
||||||
SharedClassPathEntry* ent =
|
SharedClassPathEntry* ent =
|
||||||
(SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
|
(SharedClassPathEntry*)FileMapInfo::shared_path(path_index);
|
||||||
|
|
||||||
if (SystemDictionary::is_platform_class_loader(class_loader())) {
|
if (SystemDictionary::is_platform_class_loader(class_loader())) {
|
||||||
assert(ent != NULL, "shared class for PlatformClassLoader should have valid SharedClassPathEntry");
|
assert(ent != NULL, "shared class for PlatformClassLoader should have valid SharedClassPathEntry");
|
||||||
|
@ -400,7 +399,7 @@ bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
|
||||||
// PackageEntry/ModuleEntry is found in the classloader. Check if the
|
// PackageEntry/ModuleEntry is found in the classloader. Check if the
|
||||||
// ModuleEntry's location agrees with the archived class' origination.
|
// ModuleEntry's location agrees with the archived class' origination.
|
||||||
if (ent->is_modules_image() && mod_entry->location()->starts_with("jrt:")) {
|
if (ent->is_modules_image() && mod_entry->location()->starts_with("jrt:")) {
|
||||||
return true; // Module class from the "modules" jimage
|
return true; // Module class from the runtime image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (SystemDictionary::is_system_class_loader(class_loader())) {
|
} else if (SystemDictionary::is_system_class_loader(class_loader())) {
|
||||||
|
@ -409,7 +408,8 @@ bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
|
||||||
// The archived class is in the unnamed package. Currently, the boot image
|
// The archived class is in the unnamed package. Currently, the boot image
|
||||||
// does not contain any class in the unnamed package.
|
// does not contain any class in the unnamed package.
|
||||||
assert(!ent->is_modules_image(), "Class in the unnamed package must be from the classpath");
|
assert(!ent->is_modules_image(), "Class in the unnamed package must be from the classpath");
|
||||||
if (path_index >= ClassLoaderExt::app_paths_start_index()) {
|
if (path_index >= ClassLoaderExt::app_class_paths_start_index()) {
|
||||||
|
assert(path_index < ClassLoaderExt::app_module_paths_start_index(), "invalid path_index");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -421,23 +421,37 @@ bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
|
||||||
if (get_package_entry(pkg_name, ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader())) == NULL &&
|
if (get_package_entry(pkg_name, ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader())) == NULL &&
|
||||||
get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data()) == NULL) {
|
get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data()) == NULL) {
|
||||||
// The PackageEntry is not defined in any of the boot/platform/app classloaders.
|
// The PackageEntry is not defined in any of the boot/platform/app classloaders.
|
||||||
// The archived class must from -cp path and not from the run-time image.
|
// The archived class must from -cp path and not from the runtime image.
|
||||||
if (!ent->is_modules_image() && path_index >= ClassLoaderExt::app_paths_start_index()) {
|
if (!ent->is_modules_image() && path_index >= ClassLoaderExt::app_class_paths_start_index() &&
|
||||||
|
path_index < ClassLoaderExt::app_module_paths_start_index()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mod_entry != NULL) {
|
} else if (mod_entry != NULL) {
|
||||||
// The package/module is defined in the AppClassLoader. Currently we only
|
// The package/module is defined in the AppClassLoader. We support
|
||||||
// support archiving application module class from the run-time image.
|
// archiving application module class from the runtime image or from
|
||||||
|
// a named module from a module path.
|
||||||
// Packages from the -cp path are in the unnamed_module.
|
// Packages from the -cp path are in the unnamed_module.
|
||||||
if ((ent->is_modules_image() && mod_entry->location()->starts_with("jrt:")) ||
|
if (ent->is_modules_image() && mod_entry->location()->starts_with("jrt:")) {
|
||||||
(pkg_entry->in_unnamed_module() && path_index >= ClassLoaderExt::app_paths_start_index())) {
|
// shared module class from runtime image
|
||||||
|
return true;
|
||||||
|
} else if (pkg_entry->in_unnamed_module() && path_index >= ClassLoaderExt::app_class_paths_start_index() &&
|
||||||
|
path_index < ClassLoaderExt::app_module_paths_start_index()) {
|
||||||
|
// shared class from -cp
|
||||||
DEBUG_ONLY( \
|
DEBUG_ONLY( \
|
||||||
ClassLoaderData* loader_data = class_loader_data(class_loader); \
|
ClassLoaderData* loader_data = class_loader_data(class_loader); \
|
||||||
if (pkg_entry->in_unnamed_module()) \
|
assert(mod_entry == loader_data->unnamed_module(), "the unnamed module is not defined in the classloader");)
|
||||||
assert(mod_entry == loader_data->unnamed_module(), "the unnamed module is not defined in the classloader");)
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
if(!pkg_entry->in_unnamed_module() &&
|
||||||
|
(path_index >= ClassLoaderExt::app_module_paths_start_index())&&
|
||||||
|
(path_index < FileMapInfo::get_number_of_shared_paths()) &&
|
||||||
|
(strcmp(ent->name(), ClassLoader::skip_uri_protocol(mod_entry->location()->as_C_string())) == 0)) {
|
||||||
|
// shared module class from module path
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
assert(path_index < FileMapInfo::get_number_of_shared_paths(), "invalid path_index");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ void FileMapInfo::fail_continue(const char *msg, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
MetaspaceShared::set_archive_loading_failed();
|
MetaspaceShared::set_archive_loading_failed();
|
||||||
if (PrintSharedArchiveAndExit && _validating_classpath_entry_table) {
|
if (PrintSharedArchiveAndExit && _validating_shared_path_table) {
|
||||||
// If we are doing PrintSharedArchiveAndExit and some of the classpath entries
|
// If we are doing PrintSharedArchiveAndExit and some of the classpath entries
|
||||||
// do not validate, we can still continue "limping" to validate the remaining
|
// do not validate, we can still continue "limping" to validate the remaining
|
||||||
// entries. No need to quit.
|
// entries. No need to quit.
|
||||||
|
@ -188,9 +188,9 @@ void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment
|
||||||
_max_heap_size = MaxHeapSize;
|
_max_heap_size = MaxHeapSize;
|
||||||
_narrow_klass_base = Universe::narrow_klass_base();
|
_narrow_klass_base = Universe::narrow_klass_base();
|
||||||
_narrow_klass_shift = Universe::narrow_klass_shift();
|
_narrow_klass_shift = Universe::narrow_klass_shift();
|
||||||
_classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
|
_shared_path_table_size = mapinfo->_shared_path_table_size;
|
||||||
_classpath_entry_table = mapinfo->_classpath_entry_table;
|
_shared_path_table = mapinfo->_shared_path_table;
|
||||||
_classpath_entry_size = mapinfo->_classpath_entry_size;
|
_shared_path_entry_size = mapinfo->_shared_path_entry_size;
|
||||||
|
|
||||||
// The following fields are for sanity checks for whether this archive
|
// The following fields are for sanity checks for whether this archive
|
||||||
// will function correctly with this JVM and the bootclasspath it's
|
// will function correctly with this JVM and the bootclasspath it's
|
||||||
|
@ -231,12 +231,16 @@ void SharedClassPathEntry::init(const char* name, TRAPS) {
|
||||||
strcpy(_name->data(), name);
|
strcpy(_name->data(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SharedClassPathEntry::validate() {
|
bool SharedClassPathEntry::validate(bool is_class_path) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
const char* name = this->name();
|
const char* name = this->name();
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
log_info(class, path)("checking shared classpath entry: %s", name);
|
log_info(class, path)("checking shared classpath entry: %s", name);
|
||||||
if (os::stat(name, &st) != 0) {
|
if (os::stat(name, &st) != 0 && is_class_path) {
|
||||||
|
// If the archived module path entry does not exist at runtime, it is not fatal
|
||||||
|
// (no need to invalid the shared archive) because the shared runtime visibility check
|
||||||
|
// filters out any archived module classes that do not have a matching runtime
|
||||||
|
// module path location.
|
||||||
FileMapInfo::fail_continue("Required classpath entry does not exist: %s", name);
|
FileMapInfo::fail_continue("Required classpath entry does not exist: %s", name);
|
||||||
ok = false;
|
ok = false;
|
||||||
} else if (is_dir()) {
|
} else if (is_dir()) {
|
||||||
|
@ -266,7 +270,7 @@ void SharedClassPathEntry::metaspace_pointers_do(MetaspaceClosure* it) {
|
||||||
it->push(&_manifest);
|
it->push(&_manifest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileMapInfo::allocate_classpath_entry_table() {
|
void FileMapInfo::allocate_shared_path_table() {
|
||||||
assert(DumpSharedSpaces, "Sanity");
|
assert(DumpSharedSpaces, "Sanity");
|
||||||
|
|
||||||
Thread* THREAD = Thread::current();
|
Thread* THREAD = Thread::current();
|
||||||
|
@ -279,12 +283,13 @@ void FileMapInfo::allocate_classpath_entry_table() {
|
||||||
size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
|
size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
|
||||||
int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
|
int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
|
||||||
int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
|
int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
|
||||||
int num_entries = num_boot_classpath_entries + num_app_classpath_entries;
|
int num_module_path_entries = ClassLoader::num_module_path_entries();
|
||||||
|
int num_entries = num_boot_classpath_entries + num_app_classpath_entries + num_module_path_entries;
|
||||||
size_t bytes = entry_size * num_entries;
|
size_t bytes = entry_size * num_entries;
|
||||||
|
|
||||||
_classpath_entry_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
|
_shared_path_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
|
||||||
_classpath_entry_table_size = num_entries;
|
_shared_path_table_size = num_entries;
|
||||||
_classpath_entry_size = entry_size;
|
_shared_path_entry_size = entry_size;
|
||||||
|
|
||||||
// 1. boot class path
|
// 1. boot class path
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -292,7 +297,7 @@ void FileMapInfo::allocate_classpath_entry_table() {
|
||||||
while (cpe != NULL) {
|
while (cpe != NULL) {
|
||||||
const char* type = ((cpe == jrt) ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
|
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());
|
log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
|
||||||
SharedClassPathEntry* ent = shared_classpath(i);
|
SharedClassPathEntry* ent = shared_path(i);
|
||||||
ent->init(cpe->name(), THREAD);
|
ent->init(cpe->name(), THREAD);
|
||||||
if (cpe != jrt) { // 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.
|
EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
|
||||||
|
@ -308,41 +313,66 @@ void FileMapInfo::allocate_classpath_entry_table() {
|
||||||
ClassPathEntry *acpe = ClassLoader::app_classpath_entries();
|
ClassPathEntry *acpe = ClassLoader::app_classpath_entries();
|
||||||
while (acpe != NULL) {
|
while (acpe != NULL) {
|
||||||
log_info(class, path)("add app shared path %s", acpe->name());
|
log_info(class, path)("add app shared path %s", acpe->name());
|
||||||
SharedClassPathEntry* ent = shared_classpath(i);
|
SharedClassPathEntry* ent = shared_path(i);
|
||||||
ent->init(acpe->name(), THREAD);
|
ent->init(acpe->name(), THREAD);
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
|
SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
|
||||||
acpe = acpe->next();
|
acpe = acpe->next();
|
||||||
i ++;
|
i++;
|
||||||
}
|
}
|
||||||
assert(i == num_entries, "number of app class path entry mismatch");
|
|
||||||
|
// 3. module path
|
||||||
|
ClassPathEntry *mpe = ClassLoader::module_path_entries();
|
||||||
|
while (mpe != NULL) {
|
||||||
|
log_info(class, path)("add module path %s",mpe->name());
|
||||||
|
SharedClassPathEntry* ent = shared_path(i);
|
||||||
|
ent->init(mpe->name(), THREAD);
|
||||||
|
EXCEPTION_MARK;
|
||||||
|
SharedClassUtil::update_shared_classpath(mpe, ent, THREAD);
|
||||||
|
mpe = mpe->next();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
assert(i == num_entries, "number of shared path entry mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileMapInfo::validate_classpath_entry_table() {
|
// This function should only be called during run time with UseSharedSpaces enabled.
|
||||||
_validating_classpath_entry_table = true;
|
bool FileMapInfo::validate_shared_path_table() {
|
||||||
|
_validating_shared_path_table = true;
|
||||||
|
|
||||||
int count = _header->_classpath_entry_table_size;
|
_shared_path_table = _header->_shared_path_table;
|
||||||
|
_shared_path_entry_size = _header->_shared_path_entry_size;
|
||||||
|
_shared_path_table_size = _header->_shared_path_table_size;
|
||||||
|
|
||||||
_classpath_entry_table = _header->_classpath_entry_table;
|
// Note: _app_module_paths_start_index may not have a valid value if the UseAppCDS flag
|
||||||
_classpath_entry_size = _header->_classpath_entry_size;
|
// wasn't enabled during dump time. Therefore, we need to use the smaller of
|
||||||
_classpath_entry_table_size = _header->_classpath_entry_table_size;
|
// _shared_path_table_size and _app_module_paths_start_index for the _app_module_paths_start_index.
|
||||||
|
FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
|
||||||
|
int module_paths_start_index = (header->_app_module_paths_start_index >= _shared_path_table_size) ?
|
||||||
|
_shared_path_table_size : header->_app_module_paths_start_index;
|
||||||
|
|
||||||
|
int count = _shared_path_table_size;
|
||||||
|
|
||||||
for (int i=0; i<count; i++) {
|
for (int i=0; i<count; i++) {
|
||||||
if (shared_classpath(i)->validate()) {
|
if (i < module_paths_start_index) {
|
||||||
log_info(class, path)("ok");
|
if (shared_path(i)->validate()) {
|
||||||
|
log_info(class, path)("ok");
|
||||||
|
}
|
||||||
|
} else if (i >= module_paths_start_index) {
|
||||||
|
if (shared_path(i)->validate(false /* not a class path entry */)) {
|
||||||
|
log_info(class, path)("ok");
|
||||||
|
}
|
||||||
} else if (!PrintSharedArchiveAndExit) {
|
} else if (!PrintSharedArchiveAndExit) {
|
||||||
_validating_classpath_entry_table = false;
|
_validating_shared_path_table = false;
|
||||||
_classpath_entry_table = NULL;
|
_shared_path_table = NULL;
|
||||||
_classpath_entry_table_size = 0;
|
_shared_path_table_size = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_validating_classpath_entry_table = false;
|
_validating_shared_path_table = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read the FileMapInfo information from the file.
|
// Read the FileMapInfo information from the file.
|
||||||
|
|
||||||
bool FileMapInfo::init_from_file(int fd) {
|
bool FileMapInfo::init_from_file(int fd) {
|
||||||
|
@ -925,18 +955,18 @@ void FileMapInfo::assert_mark(bool check) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileMapInfo::metaspace_pointers_do(MetaspaceClosure* it) {
|
void FileMapInfo::metaspace_pointers_do(MetaspaceClosure* it) {
|
||||||
it->push(&_classpath_entry_table);
|
it->push(&_shared_path_table);
|
||||||
for (int i=0; i<_classpath_entry_table_size; i++) {
|
for (int i=0; i<_shared_path_table_size; i++) {
|
||||||
shared_classpath(i)->metaspace_pointers_do(it);
|
shared_path(i)->metaspace_pointers_do(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FileMapInfo* FileMapInfo::_current_info = NULL;
|
FileMapInfo* FileMapInfo::_current_info = NULL;
|
||||||
Array<u8>* FileMapInfo::_classpath_entry_table = NULL;
|
Array<u8>* FileMapInfo::_shared_path_table = NULL;
|
||||||
int FileMapInfo::_classpath_entry_table_size = 0;
|
int FileMapInfo::_shared_path_table_size = 0;
|
||||||
size_t FileMapInfo::_classpath_entry_size = 0x1234baad;
|
size_t FileMapInfo::_shared_path_entry_size = 0x1234baad;
|
||||||
bool FileMapInfo::_validating_classpath_entry_table = false;
|
bool FileMapInfo::_validating_shared_path_table = false;
|
||||||
|
|
||||||
// Open the shared archive file, read and validate the header
|
// Open the shared archive file, read and validate the header
|
||||||
// information (version, boot classpath, etc.). If initialization
|
// information (version, boot classpath, etc.). If initialization
|
||||||
|
@ -946,7 +976,7 @@ bool FileMapInfo::_validating_classpath_entry_table = false;
|
||||||
// Validation of the archive is done in two steps:
|
// Validation of the archive is done in two steps:
|
||||||
//
|
//
|
||||||
// [1] validate_header() - done here. This checks the header, including _paths_misc_info.
|
// [1] validate_header() - done here. This checks the header, including _paths_misc_info.
|
||||||
// [2] validate_classpath_entry_table - this is done later, because the table is in the RW
|
// [2] validate_shared_path_table - this is done later, because the table is in the RW
|
||||||
// region of the archive, which is not mapped yet.
|
// region of the archive, which is not mapped yet.
|
||||||
bool FileMapInfo::initialize() {
|
bool FileMapInfo::initialize() {
|
||||||
assert(UseSharedSpaces, "UseSharedSpaces expected.");
|
assert(UseSharedSpaces, "UseSharedSpaces expected.");
|
||||||
|
@ -980,6 +1010,7 @@ int FileMapInfo::FileMapHeader::compute_crc() {
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function should only be called during run time with UseSharedSpaces enabled.
|
||||||
bool FileMapInfo::FileMapHeader::validate() {
|
bool FileMapInfo::FileMapHeader::validate() {
|
||||||
if (VerifySharedSpaces && compute_crc() != _crc) {
|
if (VerifySharedSpaces && compute_crc() != _crc) {
|
||||||
fail_continue("Header checksum verification failed.");
|
fail_continue("Header checksum verification failed.");
|
||||||
|
|
|
@ -53,7 +53,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
void init(const char* name, TRAPS);
|
void init(const char* name, TRAPS);
|
||||||
void metaspace_pointers_do(MetaspaceClosure* it);
|
void metaspace_pointers_do(MetaspaceClosure* it);
|
||||||
bool validate();
|
bool validate(bool is_class_path = true);
|
||||||
|
|
||||||
// The _timestamp only gets set for jar files and "modules" jimage.
|
// The _timestamp only gets set for jar files and "modules" jimage.
|
||||||
bool is_jar_or_bootimage() {
|
bool is_jar_or_bootimage() {
|
||||||
|
@ -85,10 +85,10 @@ private:
|
||||||
size_t _file_offset;
|
size_t _file_offset;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Array<u8>* _classpath_entry_table;
|
static Array<u8>* _shared_path_table;
|
||||||
static int _classpath_entry_table_size;
|
static int _shared_path_table_size;
|
||||||
static size_t _classpath_entry_size;
|
static size_t _shared_path_entry_size;
|
||||||
static bool _validating_classpath_entry_table;
|
static bool _validating_shared_path_table;
|
||||||
|
|
||||||
// FileMapHeader describes the shared space data in the file to be
|
// FileMapHeader describes the shared space data in the file to be
|
||||||
// mapped. This structure gets written to a file. It is not a class, so
|
// mapped. This structure gets written to a file. It is not a class, so
|
||||||
|
@ -153,7 +153,7 @@ public:
|
||||||
// checking the validity of the archive and is deallocated after the archive is loaded.
|
// checking the validity of the archive and is deallocated after the archive is loaded.
|
||||||
//
|
//
|
||||||
// Note that the _paths_misc_info does NOT include information for JAR files
|
// Note that the _paths_misc_info does NOT include information for JAR files
|
||||||
// that existed during dump time. Their information is stored in _classpath_entry_table.
|
// that existed during dump time. Their information is stored in _shared_path_table.
|
||||||
int _paths_misc_info_size;
|
int _paths_misc_info_size;
|
||||||
|
|
||||||
// The following is a table of all the class path entries that were used
|
// The following is a table of all the class path entries that were used
|
||||||
|
@ -167,9 +167,9 @@ public:
|
||||||
// FIXME -- if JAR files in the tail of the list were specified but not used during dumping,
|
// FIXME -- if JAR files in the tail of the list were specified but not used during dumping,
|
||||||
// they should be removed from this table, to save space and to avoid spurious
|
// they should be removed from this table, to save space and to avoid spurious
|
||||||
// loading failures during runtime.
|
// loading failures during runtime.
|
||||||
int _classpath_entry_table_size;
|
int _shared_path_table_size;
|
||||||
size_t _classpath_entry_size;
|
size_t _shared_path_entry_size;
|
||||||
Array<u8>* _classpath_entry_table;
|
Array<u8>* _shared_path_table;
|
||||||
|
|
||||||
char* region_addr(int idx);
|
char* region_addr(int idx);
|
||||||
|
|
||||||
|
@ -270,25 +270,26 @@ public:
|
||||||
// Stop CDS sharing and unmap CDS regions.
|
// Stop CDS sharing and unmap CDS regions.
|
||||||
static void stop_sharing_and_unmap(const char* msg);
|
static void stop_sharing_and_unmap(const char* msg);
|
||||||
|
|
||||||
static void allocate_classpath_entry_table();
|
static void allocate_shared_path_table();
|
||||||
bool validate_classpath_entry_table();
|
bool validate_shared_path_table();
|
||||||
|
|
||||||
static SharedClassPathEntry* shared_classpath(int index) {
|
static SharedClassPathEntry* shared_path(int index) {
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
assert(index < _classpath_entry_table_size, "sanity");
|
assert(index < _shared_path_table_size, "sanity");
|
||||||
char* p = (char*)_classpath_entry_table->data();
|
char* p = (char*)_shared_path_table->data();
|
||||||
p += _classpath_entry_size * index;
|
p += _shared_path_entry_size * index;
|
||||||
return (SharedClassPathEntry*)p;
|
return (SharedClassPathEntry*)p;
|
||||||
}
|
}
|
||||||
static const char* shared_classpath_name(int index) {
|
|
||||||
|
static const char* shared_path_name(int index) {
|
||||||
assert(index >= 0, "Sanity");
|
assert(index >= 0, "Sanity");
|
||||||
return shared_classpath(index)->name();
|
return shared_path(index)->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_number_of_share_classpaths() {
|
static int get_number_of_shared_paths() {
|
||||||
return _classpath_entry_table_size;
|
return _shared_path_table_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1619,7 +1619,6 @@ void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) {
|
||||||
void MetaspaceShared::prepare_for_dumping() {
|
void MetaspaceShared::prepare_for_dumping() {
|
||||||
Arguments::check_unsupported_dumping_properties();
|
Arguments::check_unsupported_dumping_properties();
|
||||||
ClassLoader::initialize_shared_path();
|
ClassLoader::initialize_shared_path();
|
||||||
FileMapInfo::allocate_classpath_entry_table();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preload classes from a list, populate the shared spaces and dump to a
|
// Preload classes from a list, populate the shared spaces and dump to a
|
||||||
|
@ -2001,7 +2000,7 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
|
||||||
(md_base = mapinfo->map_region(md, &md_top)) != NULL &&
|
(md_base = mapinfo->map_region(md, &md_top)) != NULL &&
|
||||||
(od_base = mapinfo->map_region(od, &od_top)) != NULL &&
|
(od_base = mapinfo->map_region(od, &od_top)) != NULL &&
|
||||||
(image_alignment == (size_t)os::vm_allocation_granularity()) &&
|
(image_alignment == (size_t)os::vm_allocation_granularity()) &&
|
||||||
mapinfo->validate_classpath_entry_table()) {
|
mapinfo->validate_shared_path_table()) {
|
||||||
// Success -- set up MetaspaceObj::_shared_metaspace_{base,top} for
|
// Success -- set up MetaspaceObj::_shared_metaspace_{base,top} for
|
||||||
// fast checking in MetaspaceShared::is_in_shared_metaspace() and
|
// fast checking in MetaspaceShared::is_in_shared_metaspace() and
|
||||||
// MetaspaceObj::is_shared().
|
// MetaspaceObj::is_shared().
|
||||||
|
|
|
@ -150,7 +150,7 @@ class Klass : public Metadata {
|
||||||
int _vtable_len;
|
int _vtable_len;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This is an index into FileMapHeader::_classpath_entry_table[], to
|
// This is an index into FileMapHeader::_shared_path_table[], to
|
||||||
// associate this class with the JAR file where it's loaded from during
|
// associate this class with the JAR file where it's loaded from during
|
||||||
// dump time. If a class is not loaded from the shared archive, this field is
|
// dump time. If a class is not loaded from the shared archive, this field is
|
||||||
// -1.
|
// -1.
|
||||||
|
|
|
@ -1446,35 +1446,23 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop
|
||||||
}
|
}
|
||||||
|
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
|
const char* unsupported_properties[] = { "jdk.module.limitmods",
|
||||||
|
"jdk.module.upgrade.path",
|
||||||
|
"jdk.module.patch.0" };
|
||||||
|
const char* unsupported_options[] = { "--limit-modules",
|
||||||
|
"--upgrade-module-path",
|
||||||
|
"--patch-module"
|
||||||
|
};
|
||||||
void Arguments::check_unsupported_dumping_properties() {
|
void Arguments::check_unsupported_dumping_properties() {
|
||||||
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
|
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
|
||||||
const char* unsupported_properties[] = { "jdk.module.main",
|
|
||||||
"jdk.module.limitmods",
|
|
||||||
"jdk.module.path",
|
|
||||||
"jdk.module.upgrade.path",
|
|
||||||
"jdk.module.patch.0" };
|
|
||||||
const char* unsupported_options[] = { "-m", // cannot use at dump time
|
|
||||||
"--limit-modules", // ignored at dump time
|
|
||||||
"--module-path", // ignored at dump time
|
|
||||||
"--upgrade-module-path", // ignored at dump time
|
|
||||||
"--patch-module" // ignored at dump time
|
|
||||||
};
|
|
||||||
assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
|
assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
|
||||||
// If a vm option is found in the unsupported_options array with index less than the info_idx,
|
// If a vm option is found in the unsupported_options array, vm will exit with an error message.
|
||||||
// vm will exit with an error message. Otherwise, it will print an informational message if
|
|
||||||
// -Xlog:cds is enabled.
|
|
||||||
uint info_idx = 1;
|
|
||||||
SystemProperty* sp = system_properties();
|
SystemProperty* sp = system_properties();
|
||||||
while (sp != NULL) {
|
while (sp != NULL) {
|
||||||
for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
|
for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
|
||||||
if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
|
if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
|
||||||
if (i < info_idx) {
|
vm_exit_during_initialization(
|
||||||
vm_exit_during_initialization(
|
"Cannot use the following option when dumping the shared archive", unsupported_options[i]);
|
||||||
"Cannot use the following option when dumping the shared archive", unsupported_options[i]);
|
|
||||||
} else {
|
|
||||||
log_info(cds)("Info: the %s option is ignored when dumping the shared archive",
|
|
||||||
unsupported_options[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sp = sp->next();
|
sp = sp->next();
|
||||||
|
@ -1485,6 +1473,20 @@ void Arguments::check_unsupported_dumping_properties() {
|
||||||
vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
|
vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Arguments::check_unsupported_cds_runtime_properties() {
|
||||||
|
assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}");
|
||||||
|
assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
|
||||||
|
for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
|
||||||
|
if (get_property(unsupported_properties[i]) != NULL) {
|
||||||
|
if (RequireSharedSpaces) {
|
||||||
|
warning("CDS is disabled when the %s option is specified.", unsupported_options[i]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//===========================================================================================================
|
//===========================================================================================================
|
||||||
|
@ -3378,6 +3380,9 @@ jint Arguments::finalize_vm_init_args(bool patch_mod_javabase) {
|
||||||
if (UseSharedSpaces && patch_mod_javabase) {
|
if (UseSharedSpaces && patch_mod_javabase) {
|
||||||
no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
|
no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
|
||||||
}
|
}
|
||||||
|
if (UseSharedSpaces && !DumpSharedSpaces && check_unsupported_cds_runtime_properties()) {
|
||||||
|
FLAG_SET_DEFAULT(UseSharedSpaces, false);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CAN_SHOW_REGISTERS_ON_ASSERT
|
#ifndef CAN_SHOW_REGISTERS_ON_ASSERT
|
||||||
|
|
|
@ -703,6 +703,8 @@ class Arguments : AllStatic {
|
||||||
|
|
||||||
static void check_unsupported_dumping_properties() NOT_CDS_RETURN;
|
static void check_unsupported_dumping_properties() NOT_CDS_RETURN;
|
||||||
|
|
||||||
|
static bool check_unsupported_cds_runtime_properties() NOT_CDS_RETURN;
|
||||||
|
|
||||||
static bool atojulong(const char *s, julong* result);
|
static bool atojulong(const char *s, julong* result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3891,6 +3891,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
||||||
// cache the system and platform class loaders
|
// cache the system and platform class loaders
|
||||||
SystemDictionary::compute_java_loaders(CHECK_JNI_ERR);
|
SystemDictionary::compute_java_loaders(CHECK_JNI_ERR);
|
||||||
|
|
||||||
|
if (DumpSharedSpaces) {
|
||||||
|
// capture the module path info from the ModuleEntryTable
|
||||||
|
ClassLoader::initialize_module_path(THREAD);
|
||||||
|
}
|
||||||
|
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
if (force_JVMCI_intialization) {
|
if (force_JVMCI_intialization) {
|
||||||
JVMCIRuntime::force_initialization(CHECK_JNI_ERR);
|
JVMCIRuntime::force_initialization(CHECK_JNI_ERR);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -32,9 +32,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.test.lib.JDKToolFinder;
|
import jdk.test.lib.JDKToolFinder;
|
||||||
|
import jdk.test.lib.compiler.CompilerUtils;
|
||||||
import jdk.test.lib.process.OutputAnalyzer;
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
import jdk.test.lib.process.ProcessTools;
|
import jdk.test.lib.process.ProcessTools;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import sun.tools.jar.Main;
|
import sun.tools.jar.Main;
|
||||||
|
|
||||||
|
@ -145,6 +147,21 @@ public class JarBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void createModularJar(String jarPath,
|
||||||
|
String classesDir,
|
||||||
|
String mainClass) throws Exception {
|
||||||
|
ArrayList<String> argList = new ArrayList<String>();
|
||||||
|
argList.add("--create");
|
||||||
|
argList.add("--file=" + jarPath);
|
||||||
|
if (mainClass != null) {
|
||||||
|
argList.add("--main-class=" + mainClass);
|
||||||
|
}
|
||||||
|
argList.add("-C");
|
||||||
|
argList.add(classesDir);
|
||||||
|
argList.add(".");
|
||||||
|
createJar(argList);
|
||||||
|
}
|
||||||
|
|
||||||
private static void createJar(ArrayList<String> args) {
|
private static void createJar(ArrayList<String> args) {
|
||||||
if (DEBUG) printIterable("createJar args: ", args);
|
if (DEBUG) printIterable("createJar args: ", args);
|
||||||
|
|
||||||
|
@ -190,6 +207,23 @@ public class JarBuilder {
|
||||||
output.shouldHaveExitValue(0);
|
output.shouldHaveExitValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void compileModule(Path src,
|
||||||
|
Path dest,
|
||||||
|
String modulePathArg // arg to --module-path
|
||||||
|
) throws Exception {
|
||||||
|
boolean compiled = false;
|
||||||
|
if (modulePathArg == null) {
|
||||||
|
compiled = CompilerUtils.compile(src, dest);
|
||||||
|
} else {
|
||||||
|
compiled = CompilerUtils.compile(src, dest,
|
||||||
|
"--module-path", modulePathArg);
|
||||||
|
}
|
||||||
|
if (!compiled) {
|
||||||
|
throw new RuntimeException("module did not compile");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void signJar() throws Exception {
|
public static void signJar() throws Exception {
|
||||||
String keyTool = JDKToolFinder.getJDKTool("keytool");
|
String keyTool = JDKToolFinder.getJDKTool("keytool");
|
||||||
String jarSigner = JDKToolFinder.getJDKTool("jarsigner");
|
String jarSigner = JDKToolFinder.getJDKTool("jarsigner");
|
||||||
|
|
|
@ -200,13 +200,18 @@ public class TestCommon extends CDSTestUtils {
|
||||||
return new Result(opts, runWithArchive(opts));
|
return new Result(opts, runWithArchive(opts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static OutputAnalyzer exec(String appJar, String... suffix) throws Exception {
|
public static OutputAnalyzer exec(String appJar, String... suffix) throws Exception {
|
||||||
AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar);
|
AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar);
|
||||||
opts.addSuffix(suffix);
|
opts.addSuffix(suffix);
|
||||||
return runWithArchive(opts);
|
return runWithArchive(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Result runWithModules(String prefix[], String upgrademodulepath, String modulepath,
|
||||||
|
String mid, String... testClassArgs) throws Exception {
|
||||||
|
AppCDSOptions opts = makeModuleOptions(prefix, upgrademodulepath, modulepath,
|
||||||
|
mid, testClassArgs);
|
||||||
|
return new Result(opts, runWithArchive(opts));
|
||||||
|
}
|
||||||
|
|
||||||
public static OutputAnalyzer execAuto(String... suffix) throws Exception {
|
public static OutputAnalyzer execAuto(String... suffix) throws Exception {
|
||||||
AppCDSOptions opts = (new AppCDSOptions());
|
AppCDSOptions opts = (new AppCDSOptions());
|
||||||
|
@ -220,10 +225,9 @@ public class TestCommon extends CDSTestUtils {
|
||||||
return runWithArchive(opts);
|
return runWithArchive(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OutputAnalyzer execModule(String prefix[], String upgrademodulepath, String modulepath,
|
|
||||||
String mid, String... testClassArgs)
|
|
||||||
throws Exception {
|
|
||||||
|
|
||||||
|
private static AppCDSOptions makeModuleOptions(String prefix[], String upgrademodulepath, String modulepath,
|
||||||
|
String mid, String testClassArgs[]) {
|
||||||
AppCDSOptions opts = (new AppCDSOptions());
|
AppCDSOptions opts = (new AppCDSOptions());
|
||||||
|
|
||||||
opts.addPrefix(prefix);
|
opts.addPrefix(prefix);
|
||||||
|
@ -234,7 +238,14 @@ public class TestCommon extends CDSTestUtils {
|
||||||
"-p", modulepath, "-m", mid);
|
"-p", modulepath, "-m", mid);
|
||||||
}
|
}
|
||||||
opts.addSuffix(testClassArgs);
|
opts.addSuffix(testClassArgs);
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OutputAnalyzer execModule(String prefix[], String upgrademodulepath, String modulepath,
|
||||||
|
String mid, String... testClassArgs)
|
||||||
|
throws Exception {
|
||||||
|
AppCDSOptions opts = makeModuleOptions(prefix, upgrademodulepath, modulepath,
|
||||||
|
mid, testClassArgs);
|
||||||
return runWithArchive(opts);
|
return runWithArchive(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -40,20 +40,15 @@ import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
|
||||||
public class CheckUnsupportedDumpingOptions {
|
public class CheckUnsupportedDumpingOptions {
|
||||||
private static final String[] jigsawOptions = {
|
private static final String[] jigsawOptions = {
|
||||||
"-m",
|
|
||||||
"--limit-modules",
|
"--limit-modules",
|
||||||
"--module-path",
|
|
||||||
"--upgrade-module-path",
|
"--upgrade-module-path",
|
||||||
"--patch-module"
|
"--patch-module"
|
||||||
};
|
};
|
||||||
private static final String[] optionValues = {
|
private static final String[] optionValues = {
|
||||||
"mymod",
|
"mymod",
|
||||||
"mymod",
|
|
||||||
"mydir",
|
|
||||||
".",
|
".",
|
||||||
"java.naming=javax.naming.spi.NamingManger"
|
"java.naming=javax.naming.spi.NamingManger"
|
||||||
};
|
};
|
||||||
private static final int infoIdx = 1;
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
String source = "package javax.naming.spi; " +
|
String source = "package javax.naming.spi; " +
|
||||||
|
@ -71,31 +66,11 @@ public class CheckUnsupportedDumpingOptions {
|
||||||
String appClasses[] = {"Hello"};
|
String appClasses[] = {"Hello"};
|
||||||
for (int i = 0; i < jigsawOptions.length; i++) {
|
for (int i = 0; i < jigsawOptions.length; i++) {
|
||||||
OutputAnalyzer output;
|
OutputAnalyzer output;
|
||||||
if (i == 5) {
|
output = TestCommon.dump(appJar, appClasses, "-Xlog:cds,cds+hashtables",
|
||||||
// --patch-module
|
jigsawOptions[i], optionValues[i]);
|
||||||
output = TestCommon.dump(appJar, appClasses, "-Xlog:cds,cds+hashtables",
|
output.shouldContain("Cannot use the following option " +
|
||||||
jigsawOptions[i] + optionValues[i] + appJar);
|
"when dumping the shared archive: " + jigsawOptions[i])
|
||||||
} else {
|
.shouldHaveExitValue(1);
|
||||||
output = TestCommon.dump(appJar, appClasses, "-Xlog:cds,cds+hashtables",
|
|
||||||
jigsawOptions[i], optionValues[i]);
|
|
||||||
}
|
|
||||||
if (i < infoIdx) {
|
|
||||||
output.shouldContain("Cannot use the following option " +
|
|
||||||
"when dumping the shared archive: " + jigsawOptions[i])
|
|
||||||
.shouldHaveExitValue(1);
|
|
||||||
} else {
|
|
||||||
output.shouldContain("Info: the " + jigsawOptions[i] +
|
|
||||||
" option is ignored when dumping the shared archive");
|
|
||||||
if (optionValues[i].equals("mymod")) {
|
|
||||||
// java will throw FindException for a module
|
|
||||||
// which cannot be found during init_phase2() of vm init
|
|
||||||
output.shouldHaveExitValue(1)
|
|
||||||
.shouldContain("java.lang.module.FindException: Module mymod not found");
|
|
||||||
} else {
|
|
||||||
output.shouldHaveExitValue(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -69,8 +69,7 @@ public class JigsawOptionsCombo {
|
||||||
private ArrayList<TestCase> testCaseTable = new ArrayList<TestCase>();
|
private ArrayList<TestCase> testCaseTable = new ArrayList<TestCase>();
|
||||||
|
|
||||||
public static String infoDuringDump(String option) {
|
public static String infoDuringDump(String option) {
|
||||||
return "Info: the " + option +
|
return "Cannot use the following option when dumping the shared archive: " + option;
|
||||||
" option is ignored when dumping the shared archive";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runTests() throws Exception {
|
public void runTests() throws Exception {
|
||||||
|
@ -78,7 +77,7 @@ public class JigsawOptionsCombo {
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"basic: Basic dump and execute, to verify the test plumbing works",
|
"basic: Basic dump and execute, to verify the test plumbing works",
|
||||||
"", "", 0,
|
"", "", 0,
|
||||||
"", "", 0) );
|
"", "", 0, true) );
|
||||||
|
|
||||||
String bcpArg = "-Xbootclasspath/a:" +
|
String bcpArg = "-Xbootclasspath/a:" +
|
||||||
TestCommon.getTestJar("hello_more.jar");
|
TestCommon.getTestJar("hello_more.jar");
|
||||||
|
@ -86,51 +85,50 @@ public class JigsawOptionsCombo {
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"Xbootclasspath/a: is OK for both dump and run time",
|
"Xbootclasspath/a: is OK for both dump and run time",
|
||||||
bcpArg, "", 0,
|
bcpArg, "", 0,
|
||||||
bcpArg, "", 0) );
|
bcpArg, "", 0, true) );
|
||||||
|
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"module-path-01: --module-path is ignored for dump time",
|
"module-path-01: --module-path is ignored for dump time",
|
||||||
"--module-path mods",
|
"--module-path mods", "", 0,
|
||||||
infoDuringDump("--module-path"), 0,
|
null, null, 0, true) );
|
||||||
null, null, 0) );
|
|
||||||
|
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"module-path-02: --module-path is ok for run time",
|
"module-path-02: --module-path is ok for run time",
|
||||||
"", "", 0,
|
"", "", 0,
|
||||||
"--module-path mods", "", 0) );
|
"--module-path mods", "", 0, true) );
|
||||||
|
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"add-modules-01: --add-modules is ok at dump time",
|
"add-modules-01: --add-modules is ok at dump time",
|
||||||
"--add-modules java.management",
|
"--add-modules java.management",
|
||||||
"", 0,
|
"", 0,
|
||||||
null, null, 0) );
|
null, null, 0, true) );
|
||||||
|
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"add-modules-02: --add-modules is ok at run time",
|
"add-modules-02: --add-modules is ok at run time",
|
||||||
"", "", 0,
|
"", "", 0,
|
||||||
"--add-modules java.management", "", 0) );
|
"--add-modules java.management", "", 0, true) );
|
||||||
|
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"limit-modules-01: --limit-modules is ignored at dump time",
|
"limit-modules-01: --limit-modules is ignored at dump time",
|
||||||
"--limit-modules java.base",
|
"--limit-modules java.base",
|
||||||
infoDuringDump("--limit-modules"), 0,
|
infoDuringDump("--limit-modules"), 1,
|
||||||
null, null, 0) );
|
null, null, 0, true) );
|
||||||
|
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"limit-modules-02: --limit-modules is ok at run time",
|
"limit-modules-02: --limit-modules is ok at run time",
|
||||||
"", "", 0,
|
"", "", 0,
|
||||||
"--limit-modules java.base", "", 0) );
|
"--limit-modules java.base", "", 0, false) );
|
||||||
|
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"upgrade-module-path-01: --upgrade-module-path is ignored at dump time",
|
"upgrade-module-path-01: --upgrade-module-path is ignored at dump time",
|
||||||
"--upgrade-module-path mods",
|
"--upgrade-module-path mods",
|
||||||
infoDuringDump("--upgrade-module-path"), 0,
|
infoDuringDump("--upgrade-module-path"), 1,
|
||||||
null, null, 0) );
|
null, null, 0, true) );
|
||||||
|
|
||||||
testCaseTable.add(new TestCase(
|
testCaseTable.add(new TestCase(
|
||||||
"-upgrade-module-path-module-path-02: --upgrade-module-path is ok at run time",
|
"-upgrade-module-path-module-path-02: --upgrade-module-path is ok at run time",
|
||||||
"", "", 0,
|
"", "", 0,
|
||||||
"--upgrade-module-path mods", "", 0) );
|
"--upgrade-module-path mods", "", 0, false) );
|
||||||
|
|
||||||
for (TestCase tc : testCaseTable) tc.execute();
|
for (TestCase tc : testCaseTable) tc.execute();
|
||||||
}
|
}
|
||||||
|
@ -145,6 +143,7 @@ public class JigsawOptionsCombo {
|
||||||
String runTimeArgs;
|
String runTimeArgs;
|
||||||
String runTimeExpectedOutput;
|
String runTimeExpectedOutput;
|
||||||
int runTimeExpectedExitValue;
|
int runTimeExpectedExitValue;
|
||||||
|
boolean sharingOn;
|
||||||
|
|
||||||
private String appJar = TestCommon.getTestJar("hello.jar");
|
private String appJar = TestCommon.getTestJar("hello.jar");
|
||||||
private String appClasses[] = {"Hello"};
|
private String appClasses[] = {"Hello"};
|
||||||
|
@ -152,7 +151,8 @@ public class JigsawOptionsCombo {
|
||||||
|
|
||||||
public TestCase(String description,
|
public TestCase(String description,
|
||||||
String dumpTimeArgs, String dumpTimeExpectedOutput, int dumpTimeExpectedExitValue,
|
String dumpTimeArgs, String dumpTimeExpectedOutput, int dumpTimeExpectedExitValue,
|
||||||
String runTimeArgs, String runTimeExpectedOutput, int runTimeExpectedExitValue) {
|
String runTimeArgs, String runTimeExpectedOutput, int runTimeExpectedExitValue,
|
||||||
|
boolean sharingOn) {
|
||||||
|
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.dumpTimeArgs = dumpTimeArgs;
|
this.dumpTimeArgs = dumpTimeArgs;
|
||||||
|
@ -161,6 +161,7 @@ public class JigsawOptionsCombo {
|
||||||
this.runTimeArgs = runTimeArgs;
|
this.runTimeArgs = runTimeArgs;
|
||||||
this.runTimeExpectedOutput = runTimeExpectedOutput;
|
this.runTimeExpectedOutput = runTimeExpectedOutput;
|
||||||
this.runTimeExpectedExitValue = runTimeExpectedExitValue;
|
this.runTimeExpectedExitValue = runTimeExpectedExitValue;
|
||||||
|
this.sharingOn = sharingOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,7 +184,13 @@ public class JigsawOptionsCombo {
|
||||||
OutputAnalyzer execOutput = TestCommon.exec(appJar, getRunOptions());
|
OutputAnalyzer execOutput = TestCommon.exec(appJar, getRunOptions());
|
||||||
|
|
||||||
if (runTimeExpectedExitValue == 0) {
|
if (runTimeExpectedExitValue == 0) {
|
||||||
TestCommon.checkExec(execOutput, runTimeExpectedOutput, "Hello World");
|
if (sharingOn) {
|
||||||
|
TestCommon.checkExec(execOutput, runTimeExpectedOutput, "Hello World");
|
||||||
|
} else {
|
||||||
|
execOutput.shouldHaveExitValue(0)
|
||||||
|
.shouldContain(runTimeExpectedOutput)
|
||||||
|
.shouldContain("Hello World");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
execOutput.shouldMatch(dumpTimeExpectedOutput);
|
execOutput.shouldMatch(dumpTimeExpectedOutput);
|
||||||
execOutput.shouldHaveExitValue(dumpTimeExpectedExitValue);
|
execOutput.shouldHaveExitValue(dumpTimeExpectedExitValue);
|
||||||
|
|
|
@ -86,7 +86,8 @@ public class AppClassInCP {
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
"--patch-module=java.naming=" + moduleJar,
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello");
|
"PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello");
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
output.shouldHaveExitValue(1)
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
String classPath = appJar + File.pathSeparator + classDir;
|
String classPath = appJar + File.pathSeparator + classDir;
|
||||||
System.out.println("classPath: " + classPath);
|
System.out.println("classPath: " + classPath);
|
||||||
|
@ -96,9 +97,6 @@ public class AppClassInCP {
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
"--patch-module=java.naming=" + moduleJar,
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello")
|
"PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello")
|
||||||
.assertNormalExit(
|
.assertSilentlyDisabledCDS(0, "I pass!", "Hello!");
|
||||||
"I pass!",
|
|
||||||
"Hello!",
|
|
||||||
"Hello source: shared objects file");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,8 @@ public class CustomPackage {
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"PatchMain", "javax.naming.myspi.NamingManager");
|
"PatchMain", "javax.naming.myspi.NamingManager");
|
||||||
TestCommon.checkDump(output, "Preload Warning: Cannot find javax/naming/myspi/NamingManager");
|
output.shouldHaveExitValue(1)
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
TestCommon.run(
|
TestCommon.run(
|
||||||
"-XX:+UnlockDiagnosticVMOptions",
|
"-XX:+UnlockDiagnosticVMOptions",
|
||||||
|
@ -78,6 +79,6 @@ public class CustomPackage {
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"PatchMain", "javax.naming.myspi.NamingManager")
|
"PatchMain", "javax.naming.myspi.NamingManager")
|
||||||
.assertNormalExit("I pass!");
|
.assertSilentlyDisabledCDS(0, "I pass!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,64 +62,24 @@ public class MismatchedPatchModule {
|
||||||
JarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
|
JarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
|
||||||
moduleJar = TestCommon.getTestJar("javanaming.jar");
|
moduleJar = TestCommon.getTestJar("javanaming.jar");
|
||||||
|
|
||||||
// Case 1: --patch-module specified for dump time and run time
|
// Case 1: --patch-module specified for dump time
|
||||||
System.out.println("Case 1: --patch-module specified for dump time and run time");
|
System.out.println("Case 1: --patch-module specified for dump time and run time");
|
||||||
OutputAnalyzer output =
|
OutputAnalyzer output =
|
||||||
TestCommon.dump(null,
|
TestCommon.dump(null,
|
||||||
TestCommon.list("javax/naming/spi/NamingManager"),
|
TestCommon.list("javax/naming/spi/NamingManager"),
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
"--patch-module=java.naming=" + moduleJar,
|
||||||
"PatchMain", "javax.naming.spi.NamingManager");
|
"PatchMain", "javax.naming.spi.NamingManager");
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
output.shouldHaveExitValue(1)
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
// javax.naming.spi.NamingManager is not patched at runtime
|
// Case 2: --patch-module specified for run time but not for dump time
|
||||||
TestCommon.run(
|
System.out.println("Case 2: --patch-module specified for run time but not for dump time");
|
||||||
"-XX:+UnlockDiagnosticVMOptions",
|
|
||||||
"--patch-module=java.naming2=" + moduleJar,
|
|
||||||
"-Xlog:class+path=info",
|
|
||||||
"PatchMain", "javax.naming.spi.NamingManager")
|
|
||||||
.assertNormalExit(o -> o.shouldNotContain("I pass!"));
|
|
||||||
|
|
||||||
// Case 2: --patch-module specified for dump time but not for run time
|
|
||||||
System.out.println("Case 2: --patch-module specified for dump time but not for run time");
|
|
||||||
output =
|
|
||||||
TestCommon.dump(null,
|
|
||||||
TestCommon.list("javax/naming/spi/NamingManager"),
|
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
|
||||||
"PatchMain", "javax.naming.spi.NamingManager");
|
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
|
||||||
|
|
||||||
// javax.naming.spi.NamingManager is not patched at runtime
|
|
||||||
TestCommon.run(
|
|
||||||
"-XX:+UnlockDiagnosticVMOptions",
|
|
||||||
"-Xlog:class+path=info",
|
|
||||||
"PatchMain", "javax.naming.spi.NamingManager")
|
|
||||||
.assertNormalExit(o -> o.shouldNotContain("I pass!"));
|
|
||||||
|
|
||||||
// Case 3: --patch-module specified for run time but not for dump time
|
|
||||||
System.out.println("Case 3: --patch-module specified for run time but not for dump time");
|
|
||||||
output =
|
output =
|
||||||
TestCommon.dump(null,
|
TestCommon.dump(null,
|
||||||
TestCommon.list("javax/naming/spi/NamingManager"),
|
TestCommon.list("javax/naming/spi/NamingManager"),
|
||||||
"PatchMain", "javax.naming.spi.NamingManager");
|
"PatchMain", "javax.naming.spi.NamingManager");
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
TestCommon.checkDump(output, "Loading classes to share");
|
||||||
|
|
||||||
// javax.naming.spi.NamingManager is patched at runtime
|
|
||||||
TestCommon.run(
|
|
||||||
"-XX:+UnlockDiagnosticVMOptions",
|
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
|
||||||
"-Xlog:class+path=info",
|
|
||||||
"PatchMain", "javax.naming.spi.NamingManager")
|
|
||||||
.assertNormalExit("I pass!");
|
|
||||||
|
|
||||||
// Case 4: mismatched --patch-module entry counts between dump time and run time
|
|
||||||
System.out.println("Case 4: mismatched --patch-module entry counts between dump time and run time");
|
|
||||||
output =
|
|
||||||
TestCommon.dump(null,
|
|
||||||
TestCommon.list("javax/naming/spi/NamingManager"),
|
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
|
||||||
"PatchMain", "javax.naming.spi.NamingManager");
|
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
|
||||||
|
|
||||||
// javax.naming.spi.NamingManager is patched at runtime
|
// javax.naming.spi.NamingManager is patched at runtime
|
||||||
TestCommon.run(
|
TestCommon.run(
|
||||||
"-XX:+UnlockDiagnosticVMOptions",
|
"-XX:+UnlockDiagnosticVMOptions",
|
||||||
|
@ -127,6 +87,6 @@ public class MismatchedPatchModule {
|
||||||
"--patch-module=java.naming2=" + moduleJar,
|
"--patch-module=java.naming2=" + moduleJar,
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"PatchMain", "javax.naming.spi.NamingManager")
|
"PatchMain", "javax.naming.spi.NamingManager")
|
||||||
.assertNormalExit("I pass!");
|
.assertSilentlyDisabledCDS(0, "I pass!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -67,7 +67,7 @@ public class PatchDir {
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
"--patch-module=java.naming=" + moduleJar,
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"PatchMain", "javax.naming.spi.NamingManager")
|
"PatchMain", "javax.naming.spi.NamingManager")
|
||||||
.shouldContain("Loading classes to share")
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module")
|
||||||
.shouldHaveExitValue(0);
|
.shouldHaveExitValue(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,8 @@ public class PatchJavaBase {
|
||||||
TestCommon.dump(null, null,
|
TestCommon.dump(null, null,
|
||||||
"--patch-module=java.base=" + moduleJar,
|
"--patch-module=java.base=" + moduleJar,
|
||||||
"PatchMain", "java.lang.NewClass");
|
"PatchMain", "java.lang.NewClass");
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
output.shouldHaveExitValue(1)
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
TestCommon.run(
|
TestCommon.run(
|
||||||
"-XX:+UnlockDiagnosticVMOptions",
|
"-XX:+UnlockDiagnosticVMOptions",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -68,7 +68,8 @@ public class Simple {
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"PatchMain", "javax.naming.spi.NamingManager");
|
"PatchMain", "javax.naming.spi.NamingManager");
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
output.shouldHaveExitValue(1)
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
TestCommon.run(
|
TestCommon.run(
|
||||||
"-XX:+UnlockDiagnosticVMOptions",
|
"-XX:+UnlockDiagnosticVMOptions",
|
||||||
|
@ -76,6 +77,6 @@ public class Simple {
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"PatchMain", "javax.naming.spi.NamingManager")
|
"PatchMain", "javax.naming.spi.NamingManager")
|
||||||
.assertNormalExit("I pass!");
|
.assertSilentlyDisabledCDS(0, "I pass!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,8 @@ public class SubClassOfPatchedClass {
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
"--patch-module=java.naming=" + moduleJar,
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"PatchMain", "javax.naming.Reference", "mypackage.MyReference");
|
"PatchMain", "javax.naming.Reference", "mypackage.MyReference");
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
output.shouldHaveExitValue(1)
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
String classPath = appJar + File.pathSeparator + classDir;
|
String classPath = appJar + File.pathSeparator + classDir;
|
||||||
System.out.println("classPath: " + classPath);
|
System.out.println("classPath: " + classPath);
|
||||||
|
@ -98,8 +99,6 @@ public class SubClassOfPatchedClass {
|
||||||
"--patch-module=java.naming=" + moduleJar,
|
"--patch-module=java.naming=" + moduleJar,
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"PatchMain", "javax.naming.Reference", "mypackage.MyReference")
|
"PatchMain", "javax.naming.Reference", "mypackage.MyReference")
|
||||||
.assertNormalExit(
|
.assertSilentlyDisabledCDS(0, "MyReference source: file:", "I pass!");
|
||||||
"I pass!",
|
|
||||||
"MyReference source: file:");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,8 @@ public class TwoJars {
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"PatchMain", "javax.naming.spi.NamingManager");
|
"PatchMain", "javax.naming.spi.NamingManager");
|
||||||
TestCommon.checkDump(output, "Loading classes to share");
|
output.shouldHaveExitValue(1)
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
TestCommon.run(
|
TestCommon.run(
|
||||||
"-XX:+UnlockDiagnosticVMOptions",
|
"-XX:+UnlockDiagnosticVMOptions",
|
||||||
|
@ -95,6 +96,6 @@ public class TwoJars {
|
||||||
"-Xlog:class+load",
|
"-Xlog:class+load",
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"PatchMain", "javax.naming.spi.NamingManager")
|
"PatchMain", "javax.naming.spi.NamingManager")
|
||||||
.assertNormalExit("I pass");
|
.assertSilentlyDisabledCDS(0, "I pass!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -145,29 +145,32 @@ public class BootAppendTests {
|
||||||
// Test #3: A class in excluded package defined in boot module
|
// Test #3: A class in excluded package defined in boot module
|
||||||
// - should be loaded from the -Xbootclasspath/a by the boot classloader
|
// - should be loaded from the -Xbootclasspath/a by the boot classloader
|
||||||
public static void testBootAppendExcludedModuleClassWithoutAppCDS() throws Exception {
|
public static void testBootAppendExcludedModuleClassWithoutAppCDS() throws Exception {
|
||||||
CDSOptions opts = (new CDSOptions())
|
TestCommon.run(
|
||||||
.addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
|
"-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
|
||||||
"--limit-modules", "java.base")
|
"-Xlog:class+load=info",
|
||||||
.setArchiveName(testArchiveName)
|
"--limit-modules", "java.base",
|
||||||
.addSuffix(MAIN_CLASS, "Test #3", BOOT_APPEND_MODULE_CLASS, "true", "BOOT");
|
MAIN_CLASS, "Test #3", BOOT_APPEND_MODULE_CLASS, "true", "BOOT")
|
||||||
|
.assertSilentlyDisabledCDS(out -> {
|
||||||
CDSTestUtils.runWithArchiveAndCheck(opts);
|
out.shouldHaveExitValue(0)
|
||||||
|
.shouldMatch(".class.load. sun.nio.cs.ext.MyClass source:.*bootAppend.jar");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test #4: A shared class in excluded package that's archived from
|
// Test #4: A shared class in excluded package that's archived from
|
||||||
// -Xbootclasspath/a
|
// -Xbootclasspath/a
|
||||||
// - should be loaded from the archive by the bootstrap classloader
|
// - should be loaded from the jar since AppCDS will be disabled with
|
||||||
|
// the --limit-modules option
|
||||||
public static void testBootAppendExcludedModuleClassWithAppCDS() throws Exception {
|
public static void testBootAppendExcludedModuleClassWithAppCDS() throws Exception {
|
||||||
OutputAnalyzer output = TestCommon.exec(
|
TestCommon.run(
|
||||||
appJar,
|
"-cp", appJar, "-Xbootclasspath/a:" + bootAppendJar,
|
||||||
"-Xbootclasspath/a:" + bootAppendJar,
|
"-Xlog:class+load=info",
|
||||||
"--limit-modules", "java.base",
|
"--limit-modules", "java.base",
|
||||||
"-XX:+TraceClassLoading",
|
|
||||||
MAIN_CLASS,
|
MAIN_CLASS,
|
||||||
"Test #4", BOOT_APPEND_MODULE_CLASS, "true", "BOOT");
|
"Test #4", BOOT_APPEND_MODULE_CLASS, "true", "BOOT")
|
||||||
TestCommon.checkExec(output);
|
.assertSilentlyDisabledCDS(out -> {
|
||||||
if (!TestCommon.isUnableToMap(output))
|
out.shouldHaveExitValue(0)
|
||||||
output.shouldContain("[class,load] sun.nio.cs.ext.MyClass source: shared objects file");
|
.shouldMatch(".class.load. sun.nio.cs.ext.MyClass source:.*bootAppend.jar");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,28 +232,28 @@ public class BootAppendTests {
|
||||||
public static void testBootAppendAppExcludeModuleClassWithoutAppCDS()
|
public static void testBootAppendAppExcludeModuleClassWithoutAppCDS()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
CDSOptions opts = (new CDSOptions())
|
TestCommon.run(
|
||||||
.addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
|
"-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar,
|
||||||
"--limit-modules", "java.base")
|
"-Xlog:class+load=info",
|
||||||
.setArchiveName(testArchiveName)
|
"--limit-modules", "java.base",
|
||||||
.addSuffix(MAIN_CLASS, "Test #9", APP_MODULE_CLASS, "true", "BOOT");
|
MAIN_CLASS, "Test #9", APP_MODULE_CLASS, "true", "BOOT")
|
||||||
|
.assertSilentlyDisabledCDS(out -> {
|
||||||
CDSTestUtils.runWithArchiveAndCheck(opts);
|
out.shouldHaveExitValue(0)
|
||||||
|
.shouldMatch(".class.load. com.sun.tools.javac.Main2 source:.*bootAppend.jar");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test #10: A shared class in excluded package defined in jimage app module
|
// Test #10: A shared class in excluded package defined in jimage app module
|
||||||
// - should be loaded from the -Xbootclasspath/a with AppCDS
|
// - should be loaded from the -Xbootclasspath/a with AppCDS
|
||||||
public static void testBootAppendAppExcludeModuleClassAppCDS() throws Exception {
|
public static void testBootAppendAppExcludeModuleClassAppCDS() throws Exception {
|
||||||
OutputAnalyzer output = TestCommon.exec(
|
TestCommon.run(
|
||||||
appJar,
|
"-cp", appJar, "-Xbootclasspath/a:" + bootAppendJar,
|
||||||
"-Xbootclasspath/a:" + bootAppendJar,
|
"-Xlog:class+load=info",
|
||||||
"-XX:+TraceClassLoading",
|
|
||||||
"--limit-modules", "java.base",
|
"--limit-modules", "java.base",
|
||||||
MAIN_CLASS,
|
MAIN_CLASS, "Test #10", APP_MODULE_CLASS, "true", "BOOT")
|
||||||
"Test #10", APP_MODULE_CLASS, "true", "BOOT");
|
.assertSilentlyDisabledCDS(out -> {
|
||||||
TestCommon.checkExec(output);
|
out.shouldHaveExitValue(0)
|
||||||
|
.shouldMatch(".class.load. com.sun.tools.javac.Main2 source:.*bootAppend.jar");
|
||||||
if (!TestCommon.isUnableToMap(output))
|
});
|
||||||
output.shouldContain("[class,load] com.sun.tools.javac.Main2 source: shared objects file");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,13 +89,15 @@ public class EmptyClassInBootClassPath {
|
||||||
argsList.add("useAppLoader");
|
argsList.add("useAppLoader");
|
||||||
opts = new String[argsList.size()];
|
opts = new String[argsList.size()];
|
||||||
opts = argsList.toArray(opts);
|
opts = argsList.toArray(opts);
|
||||||
TestCommon.run(opts).assertNormalExit(EXPECTED_EXCEPTION);
|
TestCommon.run(opts)
|
||||||
|
.assertSilentlyDisabledCDS(0, EXPECTED_EXCEPTION);
|
||||||
|
|
||||||
// case 4: load class in bootclasspath using boot loader with '--limit-modules java.base'
|
// case 4: load class in bootclasspath using boot loader with '--limit-modules java.base'
|
||||||
argsList.remove(argsList.size() - 1);
|
argsList.remove(argsList.size() - 1);
|
||||||
argsList.add("useBootLoader");
|
argsList.add("useBootLoader");
|
||||||
opts = new String[argsList.size()];
|
opts = new String[argsList.size()];
|
||||||
opts = argsList.toArray(opts);
|
opts = argsList.toArray(opts);
|
||||||
TestCommon.run(opts).assertNormalExit(EXPECTED_EXCEPTION);
|
TestCommon.run(opts)
|
||||||
|
.assertSilentlyDisabledCDS(0, EXPECTED_EXCEPTION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -65,11 +65,22 @@ public class LimitModsHelper {
|
||||||
// Make sure we got the expected defining ClassLoader
|
// Make sure we got the expected defining ClassLoader
|
||||||
testLoader(clazz, expectedLoaders[i]);
|
testLoader(clazz, expectedLoaders[i]);
|
||||||
|
|
||||||
// Make sure the class is in the shared space
|
// Make sure the class is not in the shared space
|
||||||
if (!wb.isSharedClass(clazz)) {
|
// because CDS is disabled with --limit-modules during run time.
|
||||||
throw new RuntimeException(clazz.getName() +
|
if (excludeModIdx != -1) {
|
||||||
".class should be in the shared space. " +
|
if (wb.isSharedClass(clazz)) {
|
||||||
"loader=" + clazz.getClassLoader() + " module=" + clazz.getModule().getName());
|
throw new RuntimeException(clazz.getName() +
|
||||||
|
".class should not be in the shared space. " +
|
||||||
|
"loader=" + clazz.getClassLoader() + " module=" + clazz.getModule().getName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// class should be in the shared space if --limit-modules
|
||||||
|
// isn't specified during run time
|
||||||
|
if (!wb.isSharedClass(clazz)) {
|
||||||
|
throw new RuntimeException(clazz.getName() +
|
||||||
|
".class should be in the shared space. " +
|
||||||
|
"loader=" + clazz.getClassLoader() + " module=" + clazz.getModule().getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clazz = null;
|
clazz = null;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -150,14 +150,14 @@ public class LimitModsTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output = TestCommon.exec(
|
TestCommon.run(
|
||||||
appJar + File.pathSeparator + helperJar,
|
"-cp", appJar + File.pathSeparator + helperJar,
|
||||||
"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", bootClassPath,
|
"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", bootClassPath,
|
||||||
"--limit-modules", limitMods,
|
"--limit-modules", limitMods,
|
||||||
"LimitModsHelper",
|
"LimitModsHelper",
|
||||||
BOOT_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, APP_ARCHIVE_CLASS,
|
BOOT_ARCHIVE_CLASS, PLATFORM_ARCHIVE_CLASS, APP_ARCHIVE_CLASS,
|
||||||
Integer.toString(excludeModIdx)); // last 4 args passed to test
|
Integer.toString(excludeModIdx)) // last 4 args passed to test
|
||||||
TestCommon.checkExec(output);
|
.assertSilentlyDisabledCDS(0);
|
||||||
limitMods = null;
|
limitMods = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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
|
||||||
|
* @requires vm.cds
|
||||||
|
* @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/appcds
|
||||||
|
* @modules jdk.compiler
|
||||||
|
* jdk.jartool/sun.tools.jar
|
||||||
|
* jdk.jlink
|
||||||
|
* @run main AddModules
|
||||||
|
* @summary sanity test the --add-modules option
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import jdk.testlibrary.ProcessTools;
|
||||||
|
|
||||||
|
public class AddModules {
|
||||||
|
|
||||||
|
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
|
||||||
|
|
||||||
|
private static final String TEST_SRC = System.getProperty("test.src");
|
||||||
|
|
||||||
|
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||||
|
private static final Path MODS_DIR = Paths.get("mods");
|
||||||
|
|
||||||
|
// the module name of the test module
|
||||||
|
private static final String MAIN_MODULE1 = "com.greetings";
|
||||||
|
private static final String MAIN_MODULE2 = "com.hello";
|
||||||
|
private static final String SUB_MODULE = "org.astro";
|
||||||
|
|
||||||
|
// the module main class
|
||||||
|
private static final String MAIN_CLASS1 = "com.greetings.Main";
|
||||||
|
private static final String MAIN_CLASS2 = "com.hello.Main";
|
||||||
|
private static final String APP_CLASS = "org.astro.World";
|
||||||
|
|
||||||
|
private static Path moduleDir = null;
|
||||||
|
private static Path subJar = null;
|
||||||
|
private static Path mainJar1 = null;
|
||||||
|
private static Path mainJar2 = null;
|
||||||
|
|
||||||
|
public static void buildTestModule() throws Exception {
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(SUB_MODULE),
|
||||||
|
MODS_DIR.resolve(SUB_MODULE),
|
||||||
|
null);
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(MAIN_MODULE1),
|
||||||
|
MODS_DIR.resolve(MAIN_MODULE1),
|
||||||
|
MODS_DIR.toString());
|
||||||
|
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(MAIN_MODULE2),
|
||||||
|
MODS_DIR.resolve(MAIN_MODULE2),
|
||||||
|
MODS_DIR.toString());
|
||||||
|
|
||||||
|
moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||||
|
subJar = moduleDir.resolve(SUB_MODULE + ".jar");
|
||||||
|
String classes = MODS_DIR.resolve(SUB_MODULE).toString();
|
||||||
|
JarBuilder.createModularJar(subJar.toString(), classes, null);
|
||||||
|
|
||||||
|
mainJar1 = moduleDir.resolve(MAIN_MODULE1 + ".jar");
|
||||||
|
classes = MODS_DIR.resolve(MAIN_MODULE1).toString();
|
||||||
|
JarBuilder.createModularJar(mainJar1.toString(), classes, MAIN_CLASS1);
|
||||||
|
|
||||||
|
mainJar2 = moduleDir.resolve(MAIN_MODULE2 + ".jar");
|
||||||
|
classes = MODS_DIR.resolve(MAIN_MODULE2).toString();
|
||||||
|
JarBuilder.createModularJar(mainJar2.toString(), classes, MAIN_CLASS2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
// compile the modules and create the modular jar files
|
||||||
|
buildTestModule();
|
||||||
|
String appClasses[] = {MAIN_CLASS1, MAIN_CLASS2, APP_CLASS};
|
||||||
|
// create an archive with the classes in the modules built in the
|
||||||
|
// previous step
|
||||||
|
OutputAnalyzer output = TestCommon.createArchive(
|
||||||
|
null, appClasses,
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"--add-modules",
|
||||||
|
MAIN_MODULE1 + "," + MAIN_MODULE2);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
String prefix[] = {"-cp", "\"\"", "-Xlog:class+load=trace"};
|
||||||
|
|
||||||
|
// run the com.greetings module with the archive with the --module-path
|
||||||
|
// the same as the one during dump time.
|
||||||
|
// The classes should be loaded from the archive.
|
||||||
|
TestCommon.runWithModules(prefix,
|
||||||
|
null, // --upgrade-module-path
|
||||||
|
moduleDir.toString(), // --module-path
|
||||||
|
MAIN_MODULE1) // -m
|
||||||
|
.assertNormalExit(out -> {
|
||||||
|
out.shouldContain("[class,load] com.greetings.Main source: shared objects file")
|
||||||
|
.shouldContain("[class,load] org.astro.World source: shared objects file");
|
||||||
|
});
|
||||||
|
|
||||||
|
// run the com.hello module with the archive with the --module-path
|
||||||
|
// the same as the one during dump time.
|
||||||
|
// The classes should be loaded from the archive.
|
||||||
|
TestCommon.runWithModules(prefix,
|
||||||
|
null, // --upgrade-module-path
|
||||||
|
moduleDir.toString(), // --module-path
|
||||||
|
MAIN_MODULE2) // -m
|
||||||
|
.assertNormalExit(out -> {
|
||||||
|
out.shouldContain("[class,load] com.hello.Main source: shared objects file")
|
||||||
|
.shouldContain("[class,load] org.astro.World source: shared objects file");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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
|
||||||
|
* @requires vm.cds
|
||||||
|
* @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/appcds
|
||||||
|
* @modules jdk.compiler
|
||||||
|
* jdk.jartool/sun.tools.jar
|
||||||
|
* jdk.jlink
|
||||||
|
* @run main AddOpens
|
||||||
|
* @summary sanity test the --add-opens option
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import jdk.testlibrary.ProcessTools;
|
||||||
|
|
||||||
|
public class AddOpens {
|
||||||
|
|
||||||
|
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
|
||||||
|
|
||||||
|
private static final String TEST_SRC = System.getProperty("test.src");
|
||||||
|
|
||||||
|
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||||
|
private static final Path MODS_DIR = Paths.get("mods");
|
||||||
|
|
||||||
|
// the module name of the test module
|
||||||
|
private static final String TEST_MODULE1 = "com.simple";
|
||||||
|
|
||||||
|
// the module main class
|
||||||
|
private static final String MAIN_CLASS = "com.simple.Main";
|
||||||
|
|
||||||
|
private static Path moduleDir = null;
|
||||||
|
private static Path moduleDir2 = null;
|
||||||
|
private static Path destJar = null;
|
||||||
|
|
||||||
|
public static void buildTestModule() throws Exception {
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE1),
|
||||||
|
MODS_DIR.resolve(TEST_MODULE1),
|
||||||
|
MODS_DIR.toString());
|
||||||
|
|
||||||
|
moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||||
|
moduleDir2 = Files.createTempDirectory(USER_DIR, "mlib2");
|
||||||
|
|
||||||
|
Path srcJar = moduleDir.resolve(TEST_MODULE1 + ".jar");
|
||||||
|
destJar = moduleDir2.resolve(TEST_MODULE1 + ".jar");
|
||||||
|
String classes = MODS_DIR.resolve(TEST_MODULE1).toString();
|
||||||
|
JarBuilder.createModularJar(srcJar.toString(), classes, MAIN_CLASS);
|
||||||
|
Files.copy(srcJar, destJar);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
// compile the modules and create the modular jar files
|
||||||
|
buildTestModule();
|
||||||
|
String appClasses[] = {MAIN_CLASS};
|
||||||
|
// create an archive with both -cp and --module-path in the command line.
|
||||||
|
// Only the class in the modular jar in the --module-path will be archived;
|
||||||
|
// the class in the modular jar in the -cp won't be archived.
|
||||||
|
OutputAnalyzer output = TestCommon.createArchive(
|
||||||
|
destJar.toString(), appClasses,
|
||||||
|
"-Xlog:class+load=trace", "-XX:+PrintSystemDictionaryAtExit",
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", TEST_MODULE1);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
|
||||||
|
// run with the archive using the same command line as in dump time
|
||||||
|
// plus the "--add-opens java.base/java.lang=com.simple" option.
|
||||||
|
// The main class should be loaded from the archive.
|
||||||
|
// The setaccessible(true) on the ClassLoader.defineClass method should
|
||||||
|
// be successful.
|
||||||
|
TestCommon.run( "-Xlog:class+load=trace",
|
||||||
|
"-cp", destJar.toString(),
|
||||||
|
"--add-opens", "java.base/java.lang=" + TEST_MODULE1,
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", TEST_MODULE1, "with_add_opens")
|
||||||
|
.assertNormalExit(
|
||||||
|
"[class,load] com.simple.Main source: shared objects file",
|
||||||
|
"method.setAccessible succeeded!");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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
|
||||||
|
* @requires vm.cds
|
||||||
|
* @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/appcds
|
||||||
|
* @modules jdk.compiler
|
||||||
|
* jdk.jartool/sun.tools.jar
|
||||||
|
* jdk.jlink
|
||||||
|
* @run main AddReads
|
||||||
|
* @summary sanity test the --add-reads option
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import jdk.testlibrary.ProcessTools;
|
||||||
|
import jdk.testlibrary.Asserts;
|
||||||
|
|
||||||
|
public class AddReads {
|
||||||
|
|
||||||
|
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
|
||||||
|
|
||||||
|
private static final String TEST_SRC = System.getProperty("test.src");
|
||||||
|
|
||||||
|
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||||
|
private static final Path MODS_DIR = Paths.get("mods");
|
||||||
|
|
||||||
|
// the module name of the test module
|
||||||
|
private static final String MAIN_MODULE = "com.norequires";
|
||||||
|
private static final String SUB_MODULE = "org.astro";
|
||||||
|
|
||||||
|
// the module main class
|
||||||
|
private static final String MAIN_CLASS = "com.norequires.Main";
|
||||||
|
private static final String APP_CLASS = "org.astro.World";
|
||||||
|
|
||||||
|
private static Path moduleDir = null;
|
||||||
|
private static Path subJar = null;
|
||||||
|
private static Path mainJar = null;
|
||||||
|
|
||||||
|
public static void buildTestModule() throws Exception {
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(SUB_MODULE),
|
||||||
|
MODS_DIR.resolve(SUB_MODULE),
|
||||||
|
null);
|
||||||
|
|
||||||
|
Asserts.assertTrue(CompilerUtils
|
||||||
|
.compile(SRC_DIR.resolve(MAIN_MODULE),
|
||||||
|
MODS_DIR.resolve(MAIN_MODULE),
|
||||||
|
"-cp", MODS_DIR.resolve(SUB_MODULE).toString(),
|
||||||
|
"--add-reads", "com.norequires=ALL-UNNAMED"));
|
||||||
|
|
||||||
|
moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||||
|
subJar = moduleDir.resolve(SUB_MODULE + ".jar");
|
||||||
|
String classes = MODS_DIR.resolve(SUB_MODULE).toString();
|
||||||
|
JarBuilder.createModularJar(subJar.toString(), classes, null);
|
||||||
|
|
||||||
|
mainJar = moduleDir.resolve(MAIN_MODULE + ".jar");
|
||||||
|
classes = MODS_DIR.resolve(MAIN_MODULE).toString();
|
||||||
|
JarBuilder.createModularJar(mainJar.toString(), classes, MAIN_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
// compile the modules and create the modular jar files
|
||||||
|
buildTestModule();
|
||||||
|
String appClasses[] = {MAIN_CLASS, APP_CLASS};
|
||||||
|
// create an archive with the classes in the modules built in the
|
||||||
|
// previous step
|
||||||
|
OutputAnalyzer output = TestCommon.createArchive(
|
||||||
|
null, appClasses,
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"--add-modules", SUB_MODULE,
|
||||||
|
"--add-reads", "com.norequires=org.astro",
|
||||||
|
"-m", MAIN_MODULE);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
String prefix[] = {"-cp", "\"\"", "-Xlog:class+load=trace",
|
||||||
|
"--add-modules", SUB_MODULE,
|
||||||
|
"--add-reads", "com.norequires=org.astro"};
|
||||||
|
|
||||||
|
// run the com.norequires module with the archive with the same args
|
||||||
|
// used during dump time.
|
||||||
|
// The classes should be loaded from the archive.
|
||||||
|
TestCommon.runWithModules(prefix,
|
||||||
|
null, // --upgrade-module-path
|
||||||
|
moduleDir.toString(), // --module-path
|
||||||
|
MAIN_MODULE) // -m
|
||||||
|
.assertNormalExit(out -> {
|
||||||
|
out.shouldContain("[class,load] com.norequires.Main source: shared objects file")
|
||||||
|
.shouldContain("[class,load] org.astro.World source: shared objects file");
|
||||||
|
});
|
||||||
|
|
||||||
|
// create an archive with -cp pointing to the jar file containing the
|
||||||
|
// org.astro module and --module-path pointing to the main module
|
||||||
|
output = TestCommon.createArchive(
|
||||||
|
subJar.toString(), appClasses,
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"--add-modules", SUB_MODULE,
|
||||||
|
"--add-reads", "com.norequires=org.astro",
|
||||||
|
"-m", MAIN_MODULE);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
// run the com.norequires module with the archive with the sub-module
|
||||||
|
// in the -cp and with -add-reads=com.norequires=ALL-UNNAMED
|
||||||
|
// The main class should be loaded from the archive.
|
||||||
|
// The org.astro.World should be loaded from the jar.
|
||||||
|
String prefix2[] = {"-cp", subJar.toString(), "-Xlog:class+load=trace",
|
||||||
|
"--add-reads", "com.norequires=ALL-UNNAMED"};
|
||||||
|
TestCommon.runWithModules(prefix2,
|
||||||
|
null, // --upgrade-module-path
|
||||||
|
moduleDir.toString(), // --module-path
|
||||||
|
MAIN_MODULE) // -m
|
||||||
|
.assertNormalExit(out -> {
|
||||||
|
out.shouldContain("[class,load] com.norequires.Main source: shared objects file")
|
||||||
|
.shouldMatch(".class.load. org.astro.World source:.*org.astro.jar");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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
|
||||||
|
* @requires vm.cds
|
||||||
|
* @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/appcds
|
||||||
|
* @modules jdk.compiler
|
||||||
|
* jdk.jartool/sun.tools.jar
|
||||||
|
* jdk.jlink
|
||||||
|
* @run main ExportModule
|
||||||
|
* @summary Tests involve exporting a module from the module path to a jar in the -cp.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import jdk.test.lib.compiler.CompilerUtils;
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import jdk.testlibrary.ProcessTools;
|
||||||
|
import jdk.testlibrary.Asserts;
|
||||||
|
|
||||||
|
public class ExportModule {
|
||||||
|
|
||||||
|
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
|
||||||
|
|
||||||
|
private static final String TEST_SRC = System.getProperty("test.src");
|
||||||
|
|
||||||
|
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||||
|
private static final Path MODS_DIR = Paths.get("mods");
|
||||||
|
|
||||||
|
// the module name of the test module
|
||||||
|
private static final String TEST_MODULE1 = "com.greetings";
|
||||||
|
private static final String TEST_MODULE2 = "org.astro";
|
||||||
|
|
||||||
|
// unnamed module package name
|
||||||
|
private static final String PKG_NAME = "com.nomodule";
|
||||||
|
|
||||||
|
// the module main class
|
||||||
|
private static final String MAIN_CLASS = "com.greetings.Main";
|
||||||
|
private static final String APP_CLASS = "org.astro.World";
|
||||||
|
|
||||||
|
// unnamed module main class
|
||||||
|
private static final String UNNAMED_MAIN = "com.nomodule.Main";
|
||||||
|
|
||||||
|
private static Path moduleDir = null;
|
||||||
|
private static Path moduleDir2 = null;
|
||||||
|
private static Path appJar = null;
|
||||||
|
private static Path appJar2 = null;
|
||||||
|
|
||||||
|
public static void buildTestModule() throws Exception {
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE2),
|
||||||
|
MODS_DIR.resolve(TEST_MODULE2),
|
||||||
|
null);
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE1),
|
||||||
|
MODS_DIR.resolve(TEST_MODULE1),
|
||||||
|
MODS_DIR.toString());
|
||||||
|
|
||||||
|
moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||||
|
Path jar = moduleDir.resolve(TEST_MODULE2 + ".jar");
|
||||||
|
String classes = MODS_DIR.resolve(TEST_MODULE2).toString();
|
||||||
|
JarBuilder.createModularJar(jar.toString(), classes, null);
|
||||||
|
|
||||||
|
moduleDir2 = Files.createTempDirectory(USER_DIR, "mlib2");
|
||||||
|
appJar = moduleDir2.resolve(TEST_MODULE1 + ".jar");
|
||||||
|
classes = MODS_DIR.resolve(TEST_MODULE1).toString();
|
||||||
|
JarBuilder.createModularJar(appJar.toString(), classes, MAIN_CLASS);
|
||||||
|
|
||||||
|
// build a non-modular jar containing the main class which
|
||||||
|
// requires the org.astro package
|
||||||
|
boolean compiled
|
||||||
|
= CompilerUtils.compile(SRC_DIR.resolve(PKG_NAME),
|
||||||
|
MODS_DIR.resolve(PKG_NAME),
|
||||||
|
"--module-path", MODS_DIR.toString(),
|
||||||
|
"--add-modules", TEST_MODULE2,
|
||||||
|
"--add-exports", "org.astro/org.astro=ALL-UNNAMED");
|
||||||
|
Asserts.assertTrue(compiled, "test package did not compile");
|
||||||
|
|
||||||
|
appJar2 = moduleDir2.resolve(PKG_NAME + ".jar");
|
||||||
|
classes = MODS_DIR.resolve(PKG_NAME).toString();
|
||||||
|
JarBuilder.createModularJar(appJar2.toString(), classes, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
// compile the modules and create the modular jar files
|
||||||
|
buildTestModule();
|
||||||
|
String appClasses[] = {MAIN_CLASS, APP_CLASS};
|
||||||
|
// create an archive with the class in the org.astro module built in the
|
||||||
|
// previous step and the main class from the modular jar in the -cp
|
||||||
|
// note: the main class is in the modular jar in the -cp which requires
|
||||||
|
// the module in the --module-path
|
||||||
|
OutputAnalyzer output = TestCommon.createArchive(
|
||||||
|
appJar.toString(), appClasses,
|
||||||
|
"-Xlog:class+load=trace", "-XX:+PrintSystemDictionaryAtExit",
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"--add-modules", TEST_MODULE2, MAIN_CLASS);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
|
||||||
|
// run it using the archive
|
||||||
|
// both the main class and the class from the org.astro module should
|
||||||
|
// be loaded from the archive
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", appJar.toString(),
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"--add-modules", TEST_MODULE2, MAIN_CLASS)
|
||||||
|
.assertNormalExit(
|
||||||
|
"[class,load] org.astro.World source: shared objects file",
|
||||||
|
"[class,load] com.greetings.Main source: shared objects file");
|
||||||
|
|
||||||
|
String appClasses2[] = {UNNAMED_MAIN, APP_CLASS};
|
||||||
|
// create an archive with the main class from a non-modular jar in the
|
||||||
|
// -cp and the class from the org.astro module
|
||||||
|
// note: the org.astro package needs to be exported to "ALL-UNNAMED"
|
||||||
|
// module since the jar in the -cp is a non-modular jar and thus it is
|
||||||
|
// unnmaed.
|
||||||
|
output = TestCommon.createArchive(
|
||||||
|
appJar2.toString(), appClasses2,
|
||||||
|
"-Xlog:class+load=trace", "-XX:+PrintSystemDictionaryAtExit",
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"--add-modules", TEST_MODULE2,
|
||||||
|
"--add-exports", "org.astro/org.astro=ALL-UNNAMED",
|
||||||
|
UNNAMED_MAIN);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
|
||||||
|
// both the main class and the class from the org.astro module should
|
||||||
|
// be loaded from the archive
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", appJar2.toString(),
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"--add-modules", TEST_MODULE2,
|
||||||
|
"--add-exports", "org.astro/org.astro=ALL-UNNAMED",
|
||||||
|
UNNAMED_MAIN)
|
||||||
|
.assertNormalExit(
|
||||||
|
"[class,load] org.astro.World source: shared objects file",
|
||||||
|
"[class,load] com.nomodule.Main source: shared objects file");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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 JvmtiEnv::AddToBootstrapClassLoaderSearch and JvmtiEnv::AddToSystemClassLoaderSearch should disable AppCDS
|
||||||
|
* @requires vm.cds
|
||||||
|
* @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/appcds
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.management
|
||||||
|
* jdk.jartool/sun.tools.jar
|
||||||
|
* @build sun.hotspot.WhiteBox
|
||||||
|
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
* @compile ../../test-classes/JvmtiApp.java
|
||||||
|
* @run main JvmtiAddPath
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
||||||
|
public class JvmtiAddPath {
|
||||||
|
static String use_whitebox_jar;
|
||||||
|
static String[] no_extra_matches = {};
|
||||||
|
static String[] check_appcds_enabled = {
|
||||||
|
"[class,load] ExtraClass source: shared object"
|
||||||
|
};
|
||||||
|
static String[] check_appcds_disabled = {
|
||||||
|
"[class,load] ExtraClass source: file:"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
|
||||||
|
|
||||||
|
private static final String TEST_SRC = System.getProperty("test.src");
|
||||||
|
|
||||||
|
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||||
|
private static final Path MODS_DIR = Paths.get("mods");
|
||||||
|
|
||||||
|
// the module name of the test module
|
||||||
|
private static final String TEST_MODULE1 = "com.simple";
|
||||||
|
|
||||||
|
// the module main class
|
||||||
|
private static final String MAIN_CLASS = "com.simple.Main";
|
||||||
|
|
||||||
|
private static Path moduleDir = null;
|
||||||
|
private static Path mainJar = null;
|
||||||
|
|
||||||
|
public static void buildTestModule() throws Exception {
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE1),
|
||||||
|
MODS_DIR.resolve(TEST_MODULE1),
|
||||||
|
MODS_DIR.toString());
|
||||||
|
|
||||||
|
moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||||
|
|
||||||
|
mainJar = moduleDir.resolve(TEST_MODULE1 + ".jar");
|
||||||
|
String classes = MODS_DIR.resolve(TEST_MODULE1).toString();
|
||||||
|
JarBuilder.createModularJar(mainJar.toString(), classes, MAIN_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run(String cp, String... args) throws Exception {
|
||||||
|
run(no_extra_matches, cp, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run(String[] extra_matches, String cp, String... args) throws Exception {
|
||||||
|
String[] opts = {"-cp", cp, "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", use_whitebox_jar};
|
||||||
|
opts = TestCommon.concat(opts, args);
|
||||||
|
TestCommon.run(opts).assertNormalExit(extra_matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
buildTestModule();
|
||||||
|
JarBuilder.build("jvmti_app", "JvmtiApp", "ExtraClass");
|
||||||
|
JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
|
||||||
|
|
||||||
|
// In all the test cases below, appJar does not contain Hello.class. Instead, we
|
||||||
|
// append JAR file(s) that contain Hello.class to the boot classpath, the app
|
||||||
|
// classpath, or both, and verify that Hello.class is loaded by the expected ClassLoader.
|
||||||
|
String appJar = TestCommon.getTestJar("jvmti_app.jar"); // contains JvmtiApp.class
|
||||||
|
String addappJar = mainJar.toString(); // contains Main.class
|
||||||
|
String addbootJar = mainJar.toString(); // contains Main.class
|
||||||
|
String twoAppJars = appJar + File.pathSeparator + addappJar;
|
||||||
|
String modulePath = "--module-path=" + moduleDir.toString();
|
||||||
|
String wbJar = TestCommon.getTestJar("WhiteBox.jar");
|
||||||
|
use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
|
||||||
|
|
||||||
|
OutputAnalyzer output = TestCommon.createArchive(
|
||||||
|
appJar,
|
||||||
|
TestCommon.list("JvmtiApp", "ExtraClass", MAIN_CLASS),
|
||||||
|
use_whitebox_jar,
|
||||||
|
"-Xlog:class+load=trace",
|
||||||
|
modulePath);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
|
||||||
|
System.out.println("Test case 1: not adding module path - Hello.class should not be found");
|
||||||
|
run(check_appcds_enabled, appJar,
|
||||||
|
"-Xlog:class+load", "JvmtiApp", "noadd", MAIN_CLASS); // appcds should be enabled
|
||||||
|
|
||||||
|
System.out.println("Test case 2: add to boot classpath only - should find Hello.class in boot loader");
|
||||||
|
run(check_appcds_disabled, appJar,
|
||||||
|
"-Xlog:class+load=trace",
|
||||||
|
modulePath,
|
||||||
|
"JvmtiApp", "bootonly", addbootJar, MAIN_CLASS); // appcds should be disabled
|
||||||
|
|
||||||
|
System.out.println("Test case 3: add to app classpath only - should find Hello.class in app loader");
|
||||||
|
run(appJar, modulePath,
|
||||||
|
"JvmtiApp", "apponly", addappJar, MAIN_CLASS);
|
||||||
|
|
||||||
|
System.out.println("Test case 4: add to boot and app paths - should find Hello.class in boot loader");
|
||||||
|
run(appJar, modulePath,
|
||||||
|
"JvmtiApp", "appandboot", addbootJar, addappJar, MAIN_CLASS);
|
||||||
|
|
||||||
|
System.out.println("Test case 5: add to app using -cp, but add to boot using JVMTI - should find Hello.class in boot loader");
|
||||||
|
run(appJar, modulePath,
|
||||||
|
"JvmtiApp", "bootonly", addappJar, MAIN_CLASS);
|
||||||
|
|
||||||
|
System.out.println("Test case 6: add to app using AppCDS, but add to boot using JVMTI - should find Hello.class in boot loader");
|
||||||
|
output = TestCommon.createArchive(
|
||||||
|
appJar, TestCommon.list("JvmtiApp", "ExtraClass"),
|
||||||
|
use_whitebox_jar,
|
||||||
|
"-Xlog:class+load=trace",
|
||||||
|
modulePath);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
run(twoAppJars, modulePath,
|
||||||
|
"JvmtiApp", "bootonly", addappJar, MAIN_CLASS);
|
||||||
|
|
||||||
|
System.out.println("Test case 7: add to app using AppCDS, no JVMTI calls - should find Hello.class in app loader");
|
||||||
|
run(twoAppJars, modulePath,
|
||||||
|
"JvmtiApp", "noadd-appcds", MAIN_CLASS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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
|
||||||
|
* @requires vm.cds
|
||||||
|
* @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/appcds
|
||||||
|
* @modules jdk.compiler
|
||||||
|
* jdk.jartool/sun.tools.jar
|
||||||
|
* jdk.jlink
|
||||||
|
* @run main MainModuleOnly
|
||||||
|
* @summary Test some scenarios with a main modular jar specified in the --module-path and -cp options in the command line.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import jdk.testlibrary.ProcessTools;
|
||||||
|
|
||||||
|
public class MainModuleOnly {
|
||||||
|
|
||||||
|
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
|
||||||
|
|
||||||
|
private static final String TEST_SRC = System.getProperty("test.src");
|
||||||
|
|
||||||
|
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||||
|
private static final Path MODS_DIR = Paths.get("mods");
|
||||||
|
|
||||||
|
// the module name of the test module
|
||||||
|
private static final String TEST_MODULE1 = "com.simple";
|
||||||
|
|
||||||
|
// the module main class
|
||||||
|
private static final String MAIN_CLASS = "com.simple.Main";
|
||||||
|
|
||||||
|
private static Path moduleDir = null;
|
||||||
|
private static Path moduleDir2 = null;
|
||||||
|
private static Path destJar = null;
|
||||||
|
|
||||||
|
public static void buildTestModule() throws Exception {
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE1),
|
||||||
|
MODS_DIR.resolve(TEST_MODULE1),
|
||||||
|
MODS_DIR.toString());
|
||||||
|
|
||||||
|
|
||||||
|
moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||||
|
moduleDir2 = Files.createTempDirectory(USER_DIR, "mlib2");
|
||||||
|
|
||||||
|
Path srcJar = moduleDir.resolve(TEST_MODULE1 + ".jar");
|
||||||
|
destJar = moduleDir2.resolve(TEST_MODULE1 + ".jar");
|
||||||
|
String classes = MODS_DIR.resolve(TEST_MODULE1).toString();
|
||||||
|
JarBuilder.createModularJar(srcJar.toString(), classes, MAIN_CLASS);
|
||||||
|
Files.copy(srcJar, destJar);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
// compile the modules and create the modular jar files
|
||||||
|
buildTestModule();
|
||||||
|
String appClasses[] = {MAIN_CLASS};
|
||||||
|
// create an archive with both -cp and --module-path in the command line.
|
||||||
|
// Only the class in the modular jar in the --module-path will be archived;
|
||||||
|
// the class in the modular jar in the -cp won't be archived.
|
||||||
|
OutputAnalyzer output = TestCommon.createArchive(
|
||||||
|
destJar.toString(), appClasses,
|
||||||
|
"-Xlog:class+load=trace", "-XX:+PrintSystemDictionaryAtExit",
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", TEST_MODULE1);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
|
||||||
|
// run with the archive using the same command line as in dump time.
|
||||||
|
// The main class should be loaded from the archive.
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", destJar.toString(),
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", TEST_MODULE1)
|
||||||
|
.assertNormalExit("[class,load] com.simple.Main source: shared objects file");
|
||||||
|
|
||||||
|
// run with the archive with the main class name inserted before the -m.
|
||||||
|
// The main class name will be picked up before the module name. So the
|
||||||
|
// main class should be loaded from the jar in the -cp.
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", destJar.toString(),
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
MAIN_CLASS, "-m", TEST_MODULE1)
|
||||||
|
.assertNormalExit(out ->
|
||||||
|
out.shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar"));
|
||||||
|
|
||||||
|
// run with the archive with exploded module. Since during dump time, we
|
||||||
|
// only archive classes from the modular jar in the --module-path, the
|
||||||
|
// main class should be loaded from the exploded module directory.
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", destJar.toString(),
|
||||||
|
"--module-path", MODS_DIR.toString(),
|
||||||
|
"-m", TEST_MODULE1 + "/" + MAIN_CLASS)
|
||||||
|
.assertNormalExit(out -> {
|
||||||
|
out.shouldMatch(".class.load. com.simple.Main source:.*com.simple")
|
||||||
|
.shouldContain(MODS_DIR.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
// run with the archive with the --upgrade-module-path option.
|
||||||
|
// CDS will be disabled with this options and the main class will be
|
||||||
|
// loaded from the modular jar.
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", destJar.toString(),
|
||||||
|
"--upgrade-module-path", moduleDir.toString(),
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", TEST_MODULE1)
|
||||||
|
.assertSilentlyDisabledCDS(out -> {
|
||||||
|
out.shouldHaveExitValue(0)
|
||||||
|
.shouldMatch("CDS is disabled when the.*option is specified")
|
||||||
|
.shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar");
|
||||||
|
});
|
||||||
|
// run with the archive with the --limit-modules option.
|
||||||
|
// CDS will be disabled with this options and the main class will be
|
||||||
|
// loaded from the modular jar.
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", destJar.toString(),
|
||||||
|
"--limit-modules", "java.base," + TEST_MODULE1,
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", TEST_MODULE1)
|
||||||
|
.assertSilentlyDisabledCDS(out -> {
|
||||||
|
out.shouldHaveExitValue(0)
|
||||||
|
.shouldMatch("CDS is disabled when the.*option is specified")
|
||||||
|
.shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar");
|
||||||
|
});
|
||||||
|
// run with the archive with the --patch-module option.
|
||||||
|
// CDS will be disabled with this options and the main class will be
|
||||||
|
// loaded from the modular jar.
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", destJar.toString(),
|
||||||
|
"--patch-module", TEST_MODULE1 + "=" + MODS_DIR.toString(),
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", TEST_MODULE1)
|
||||||
|
.assertSilentlyDisabledCDS(out -> {
|
||||||
|
out.shouldHaveExitValue(0)
|
||||||
|
.shouldMatch("CDS is disabled when the.*option is specified")
|
||||||
|
.shouldMatch(".class.load. com.simple.Main source:.*com.simple.jar");
|
||||||
|
});
|
||||||
|
// modify the timestamp of the jar file
|
||||||
|
(new File(destJar.toString())).setLastModified(System.currentTimeMillis() + 2000);
|
||||||
|
// run with the archive and the jar with modified timestamp.
|
||||||
|
// It should fail due to timestamp of the jar doesn't match the one
|
||||||
|
// used during dump time.
|
||||||
|
TestCommon.run("-Xlog:class+load=trace",
|
||||||
|
"-cp", destJar.toString(),
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", TEST_MODULE1)
|
||||||
|
.assertAbnormalExit(
|
||||||
|
"A jar/jimage file is not the one used while building the shared archive file:");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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
|
||||||
|
* @requires vm.cds
|
||||||
|
* @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/appcds
|
||||||
|
* @modules jdk.compiler
|
||||||
|
* jdk.jartool/sun.tools.jar
|
||||||
|
* jdk.jlink
|
||||||
|
* @run main ModulePathAndCP
|
||||||
|
* @summary 2 sets of tests: one with only --module-path in the command line;
|
||||||
|
* another with both -cp and --module-path in the command line.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import jdk.testlibrary.ProcessTools;
|
||||||
|
|
||||||
|
public class ModulePathAndCP {
|
||||||
|
|
||||||
|
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
|
||||||
|
|
||||||
|
private static final String TEST_SRC = System.getProperty("test.src");
|
||||||
|
|
||||||
|
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||||
|
private static final Path MODS_DIR = Paths.get("mods");
|
||||||
|
|
||||||
|
// the module name of the test module
|
||||||
|
private static final String MAIN_MODULE = "com.greetings";
|
||||||
|
private static final String APP_MODULE = "org.astro";
|
||||||
|
|
||||||
|
// the module main class
|
||||||
|
private static final String MAIN_CLASS = "com.greetings.Main";
|
||||||
|
private static final String APP_CLASS = "org.astro.World";
|
||||||
|
|
||||||
|
private static Path moduleDir = null;
|
||||||
|
private static Path moduleDir2 = null;
|
||||||
|
private static Path subJar = null;
|
||||||
|
private static Path mainJar = null;
|
||||||
|
private static Path destJar = null;
|
||||||
|
|
||||||
|
public static void buildTestModule() throws Exception {
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(APP_MODULE),
|
||||||
|
MODS_DIR.resolve(APP_MODULE),
|
||||||
|
null);
|
||||||
|
|
||||||
|
// javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
|
||||||
|
JarBuilder.compileModule(SRC_DIR.resolve(MAIN_MODULE),
|
||||||
|
MODS_DIR.resolve(MAIN_MODULE),
|
||||||
|
MODS_DIR.toString());
|
||||||
|
|
||||||
|
moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
|
||||||
|
moduleDir2 = Files.createTempDirectory(USER_DIR, "mlib2");
|
||||||
|
subJar = moduleDir.resolve(APP_MODULE + ".jar");
|
||||||
|
destJar = moduleDir2.resolve(APP_MODULE + ".jar");
|
||||||
|
String classes = MODS_DIR.resolve(APP_MODULE).toString();
|
||||||
|
JarBuilder.createModularJar(subJar.toString(), classes, null);
|
||||||
|
Files.copy(subJar, destJar);
|
||||||
|
|
||||||
|
mainJar = moduleDir.resolve(MAIN_MODULE + ".jar");
|
||||||
|
Path mainJar2 = moduleDir2.resolve(MAIN_MODULE + ".jar");
|
||||||
|
classes = MODS_DIR.resolve(MAIN_MODULE).toString();
|
||||||
|
JarBuilder.createModularJar(mainJar.toString(), classes, MAIN_CLASS);
|
||||||
|
Files.copy(mainJar, mainJar2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
// compile the modules and create the modular jar files
|
||||||
|
buildTestModule();
|
||||||
|
String appClasses[] = {MAIN_CLASS, APP_CLASS};
|
||||||
|
// create an archive with the classes in the modules built in the
|
||||||
|
// previous step
|
||||||
|
OutputAnalyzer output = TestCommon.createArchive(
|
||||||
|
null, appClasses,
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", MAIN_MODULE);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
String prefix[] = {"-cp", "\"\"", "-Xlog:class+load=trace"};
|
||||||
|
|
||||||
|
// run with the archive with the --module-path the same as the one during
|
||||||
|
// dump time. The classes should be loaded from the archive.
|
||||||
|
TestCommon.runWithModules(prefix,
|
||||||
|
null, // --upgrade-module-path
|
||||||
|
moduleDir.toString(), // --module-path
|
||||||
|
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");
|
||||||
|
});
|
||||||
|
|
||||||
|
// run with the archive with the --module-path different from the one during
|
||||||
|
// dump time. The classes should be loaded from the jar files.
|
||||||
|
TestCommon.runWithModules(prefix,
|
||||||
|
null, // --upgrade-module-path
|
||||||
|
moduleDir2.toString(), // --module-path
|
||||||
|
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");
|
||||||
|
});
|
||||||
|
|
||||||
|
// create an archive with modular jar files in both -cp and --module-path
|
||||||
|
String jars = subJar.toString() + System.getProperty("path.separator") +
|
||||||
|
mainJar.toString();
|
||||||
|
output = TestCommon.createArchive( jars, appClasses,
|
||||||
|
"-Xlog:class+load=trace", "-XX:+PrintSystemDictionaryAtExit",
|
||||||
|
"--module-path", moduleDir.toString(),
|
||||||
|
"-m", MAIN_MODULE);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
|
||||||
|
// run with archive with the main class name specified before
|
||||||
|
// the module name with the -m option. Since the -m option was specified
|
||||||
|
// 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",
|
||||||
|
"-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");
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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",
|
||||||
|
"-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");
|
||||||
|
|
||||||
|
// create an archive with two modular jars in the --module-path
|
||||||
|
output = TestCommon.createArchive(
|
||||||
|
null, appClasses,
|
||||||
|
"--module-path", jars,
|
||||||
|
"-m", MAIN_MODULE);
|
||||||
|
TestCommon.checkDump(output);
|
||||||
|
|
||||||
|
// run with the above archive but with the modular jar containing the
|
||||||
|
// 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") +
|
||||||
|
mainJar.toString();
|
||||||
|
TestCommon.runWithModules(prefix,
|
||||||
|
null, // --upgrade-module-path
|
||||||
|
jars, // --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");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.greetings;
|
||||||
|
import org.astro.World;
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.format("Greetings %s!\n", World.name());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.greetings {
|
||||||
|
requires org.astro;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.hello;
|
||||||
|
import org.astro.World;
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.format("Hello %s!\n", World.name());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.hello {
|
||||||
|
requires org.astro;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nomodule;
|
||||||
|
import org.astro.World;
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.format("Greetings %s!\n", World.name());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.norequires;
|
||||||
|
import org.astro.World;
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.format("Hello %s!\n", World.name());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.norequires { }
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.simple;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.out.println("Hello World!");
|
||||||
|
if (args.length > 0 && args[0].equals("with_add_opens")) {
|
||||||
|
Method method = ClassLoader.class.getDeclaredMethod("defineClass",
|
||||||
|
byte[].class, int.class, int.class);
|
||||||
|
method.setAccessible(true);
|
||||||
|
System.out.println("method.setAccessible succeeded!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.simple {
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module org.astro {
|
||||||
|
exports org.astro;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.astro;
|
||||||
|
public class World {
|
||||||
|
public static String name() {
|
||||||
|
return "world";
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,9 +25,9 @@
|
||||||
import sun.hotspot.WhiteBox;
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
||||||
public class JvmtiApp {
|
public class JvmtiApp {
|
||||||
static Class forname() {
|
static Class forname(String cn) {
|
||||||
try {
|
try {
|
||||||
return Class.forName("Hello");
|
return Class.forName(cn);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,14 @@ public class JvmtiApp {
|
||||||
|
|
||||||
// See ../JvmtiAddPath.java for how the classpaths are configured.
|
// See ../JvmtiAddPath.java for how the classpaths are configured.
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
|
String cn = "Hello";
|
||||||
|
if (args.length >= 3) {
|
||||||
|
cn = args[args.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
if (args[0].equals("noadd")) {
|
if (args[0].equals("noadd")) {
|
||||||
if (forname() != null) {
|
if (forname(cn) != null) {
|
||||||
failed("Hello class was loaded unexpectedly");
|
failed(cn + " class was loaded unexpectedly");
|
||||||
}
|
}
|
||||||
// We use -verbose:class to verify that Extra.class IS loaded by AppCDS if
|
// We use -verbose:class to verify that Extra.class IS loaded by AppCDS if
|
||||||
// the boot classpath HAS NOT been appended.
|
// the boot classpath HAS NOT been appended.
|
||||||
|
@ -54,39 +59,41 @@ public class JvmtiApp {
|
||||||
|
|
||||||
if (args[0].equals("bootonly")) {
|
if (args[0].equals("bootonly")) {
|
||||||
wb.addToBootstrapClassLoaderSearch(args[1]);
|
wb.addToBootstrapClassLoaderSearch(args[1]);
|
||||||
Class cls = forname();
|
Class cls = forname(cn);
|
||||||
if (cls == null) {
|
if (cls == null) {
|
||||||
failed("Cannot find Hello class");
|
failed("Cannot find " + cn + " class");
|
||||||
}
|
}
|
||||||
if (cls.getClassLoader() != null) {
|
if (cls.getClassLoader() != null) {
|
||||||
failed("Hello class not loaded by boot classloader");
|
failed("Hello class not loaded by boot classloader");
|
||||||
}
|
}
|
||||||
} else if (args[0].equals("apponly")) {
|
} else if (args[0].equals("apponly")) {
|
||||||
wb.addToSystemClassLoaderSearch(args[1]);
|
wb.addToSystemClassLoaderSearch(args[1]);
|
||||||
Class cls = forname();
|
Class cls = forname(cn);
|
||||||
if (cls == null) {
|
if (cls == null) {
|
||||||
failed("Cannot find Hello class");
|
failed("Cannot find " + cn + " class");
|
||||||
}
|
}
|
||||||
if (cls.getClassLoader() != JvmtiApp.class.getClassLoader()) {
|
if (cls.getClassLoader() != JvmtiApp.class.getClassLoader()) {
|
||||||
failed("Hello class not loaded by app classloader");
|
failed(cn + " class not loaded by app classloader");
|
||||||
}
|
}
|
||||||
} else if (args[0].equals("noadd-appcds")) {
|
} else if (args[0].equals("noadd-appcds")) {
|
||||||
Class cls = forname();
|
cn = (args.length == 1) ? "Hello" : args[1];
|
||||||
|
Class cls = forname(cn);
|
||||||
if (cls == null) {
|
if (cls == null) {
|
||||||
failed("Cannot find Hello class");
|
failed("Cannot find " + cn + " class");
|
||||||
}
|
}
|
||||||
if (cls.getClassLoader() != JvmtiApp.class.getClassLoader()) {
|
if (cls.getClassLoader() != JvmtiApp.class.getClassLoader()) {
|
||||||
failed("Hello class not loaded by app classloader");
|
failed(cn + " class not loaded by app classloader");
|
||||||
}
|
}
|
||||||
} else if (args[0].equals("appandboot")) {
|
} else if (args[0].equals("appandboot")) {
|
||||||
wb.addToBootstrapClassLoaderSearch(args[1]);
|
wb.addToBootstrapClassLoaderSearch(args[1]);
|
||||||
wb.addToSystemClassLoaderSearch(args[2]);
|
wb.addToSystemClassLoaderSearch(args[2]);
|
||||||
Class cls = forname();
|
cn = (args.length == 3) ? "Hello" : args[3];
|
||||||
|
Class cls = forname(cn);
|
||||||
if (cls == null) {
|
if (cls == null) {
|
||||||
failed("Cannot find Hello class");
|
failed("Cannot find " + cn + " class");
|
||||||
}
|
}
|
||||||
if (cls.getClassLoader() != null) {
|
if (cls.getClassLoader() != null) {
|
||||||
failed("Hello class not loaded by boot classloader");
|
failed(cn + " class not loaded by boot classloader");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
failed("unknown option " + args[0]);
|
failed("unknown option " + args[0]);
|
||||||
|
@ -102,4 +109,4 @@ public class JvmtiApp {
|
||||||
|
|
||||||
class ExtraClass {
|
class ExtraClass {
|
||||||
static void doit() {}
|
static void doit() {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -50,7 +50,8 @@ public class PatchModuleCDS {
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"-version");
|
"-version");
|
||||||
new OutputAnalyzer(pb.start())
|
new OutputAnalyzer(pb.start())
|
||||||
.shouldContain("ro space:"); // Make sure archive got created.
|
// --patch-module is not supported during CDS dumping
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
// Case 2: Test that directory in --patch-module is supported for CDS dumping
|
// Case 2: Test that directory in --patch-module is supported for CDS dumping
|
||||||
// Create a class file in the module java.base.
|
// Create a class file in the module java.base.
|
||||||
|
@ -73,7 +74,8 @@ public class PatchModuleCDS {
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"-version");
|
"-version");
|
||||||
new OutputAnalyzer(pb.start())
|
new OutputAnalyzer(pb.start())
|
||||||
.shouldContain("ro space:"); // Make sure archive got created.
|
// --patch-module is not supported during CDS dumping
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
// Case 3a: Test CDS dumping with jar file in --patch-module
|
// Case 3a: Test CDS dumping with jar file in --patch-module
|
||||||
BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
|
BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
|
||||||
|
@ -87,7 +89,8 @@ public class PatchModuleCDS {
|
||||||
"-Xlog:class+path=info",
|
"-Xlog:class+path=info",
|
||||||
"PatchModuleMain", "javax.naming.spi.NamingManager");
|
"PatchModuleMain", "javax.naming.spi.NamingManager");
|
||||||
new OutputAnalyzer(pb.start())
|
new OutputAnalyzer(pb.start())
|
||||||
.shouldContain("ro space:"); // Make sure archive got created.
|
// --patch-module is not supported during CDS dumping
|
||||||
|
.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
|
||||||
|
|
||||||
// Case 3b: Test CDS run with jar file in --patch-module
|
// Case 3b: Test CDS run with jar file in --patch-module
|
||||||
pb = ProcessTools.createJavaProcessBuilder(
|
pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
|
|
@ -117,6 +117,7 @@ public class CDSTestUtils {
|
||||||
private final boolean hasMappingFailure;
|
private final boolean hasMappingFailure;
|
||||||
private final boolean hasAbnormalExit;
|
private final boolean hasAbnormalExit;
|
||||||
private final boolean hasNormalExit;
|
private final boolean hasNormalExit;
|
||||||
|
private final String CDS_DISABLED = "warning: CDS is disabled when the";
|
||||||
|
|
||||||
public Result(CDSOptions opts, OutputAnalyzer out) throws Exception {
|
public Result(CDSOptions opts, OutputAnalyzer out) throws Exception {
|
||||||
options = opts;
|
options = opts;
|
||||||
|
@ -126,7 +127,9 @@ public class CDSTestUtils {
|
||||||
hasNormalExit = (!hasMappingFailure) && (output.getExitValue() == 0);
|
hasNormalExit = (!hasMappingFailure) && (output.getExitValue() == 0);
|
||||||
|
|
||||||
if (hasNormalExit) {
|
if (hasNormalExit) {
|
||||||
if ("on".equals(options.xShareMode) && output.getStderr().contains("java version")) {
|
if ("on".equals(options.xShareMode) &&
|
||||||
|
output.getStderr().contains("java version") &&
|
||||||
|
!output.getStderr().contains(CDS_DISABLED)) {
|
||||||
// "-showversion" is always passed in the command-line by the execXXX methods.
|
// "-showversion" is always passed in the command-line by the execXXX methods.
|
||||||
// During normal exit, we require that the VM to show that sharing was enabled.
|
// During normal exit, we require that the VM to show that sharing was enabled.
|
||||||
output.shouldContain("sharing");
|
output.shouldContain("sharing");
|
||||||
|
@ -150,6 +153,26 @@ public class CDSTestUtils {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When {--limit-modules, --patch-module, and/or --upgrade-module-path}
|
||||||
|
// are specified, CDS is silently disabled for both -Xshare:auto and -Xshare:on.
|
||||||
|
public Result assertSilentlyDisabledCDS(Checker checker) throws Exception {
|
||||||
|
if (hasMappingFailure) {
|
||||||
|
throw new RuntimeException("Unexpected mapping failure");
|
||||||
|
}
|
||||||
|
// this comes from a JVM warning message.
|
||||||
|
output.shouldContain(CDS_DISABLED);
|
||||||
|
|
||||||
|
checker.check(output);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result assertSilentlyDisabledCDS(int exitCode, String... matches) throws Exception {
|
||||||
|
return assertSilentlyDisabledCDS((out) -> {
|
||||||
|
out.shouldHaveExitValue(exitCode);
|
||||||
|
checkMatches(out, matches);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public Result ifNormalExit(Checker checker) throws Exception {
|
public Result ifNormalExit(Checker checker) throws Exception {
|
||||||
if (hasNormalExit) {
|
if (hasNormalExit) {
|
||||||
checker.check(output);
|
checker.check(output);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue