< prev index next >
src/hotspot/share/classfile/sharedPathsMiscInfo.cpp
Print this page
@@ -26,10 +26,11 @@
#include "classfile/classLoader.hpp"
#include "classfile/sharedPathsMiscInfo.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
+#include "memory/filemap.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/arguments.hpp"
#include "runtime/os.inline.hpp"
#include "utilities/ostream.hpp"
@@ -139,15 +140,80 @@
return true;
}
bool SharedPathsMiscInfo::check(jint type, const char* path) {
+ assert(UseSharedSpaces, "runtime only");
switch (type) {
case BOOT_PATH:
- // In the future we should perform the check based on the content of the mapped archive.
- if (os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
- return fail("[BOOT classpath mismatch, actual =", Arguments::get_sysclasspath());
+ {
+ //
+ // - Archive contains boot classes only - relaxed boot path check:
+ // Extra path elements appended to the boot path at runtime are allowed.
+ //
+ // - Archive contains application or platform classes - strict boot path check:
+ // Validate the entire runtime boot path, which must be compactible
+ // with the dump time boot path. Appending boot path at runtime is not
+ // allowed.
+ //
+
+ bool relaxed_check = !FileMapInfo::current_info()->header()->has_platform_or_app_classes();
+ char* runtime_boot_path;
+ ResourceMark rm;
+ if (relaxed_check) {
+ // only check the begining portion of the runtime boot path, up to
+ // the length of the dump time boot path
+ size_t len = strlen(path);
+ runtime_boot_path = NEW_RESOURCE_ARRAY(char, len + 1);
+ strncpy(runtime_boot_path, Arguments::get_sysclasspath(), len);
+ runtime_boot_path[len] = '\0';
+ } else {
+ // check the full runtime boot path
+ runtime_boot_path = Arguments::get_sysclasspath();
+ }
+
+ // Do a quick check first with a simple
+ // strcmp(dump_time_boot_path, runtime_boot_path). If the paths are the
+ // same, the check has succeeded.
+ if (os::file_name_strcmp(path, runtime_boot_path) == 0) {
+ break; // ok
+ }
+
+ // The paths are different.
+ //
+ // - The first entry in boot path is the modules_image (guaranteed by
+ // ClassLoader::setup_boot_search_path()). Skip the first entry. The
+ // path of the runtime modules_image may be different from the dump
+ // time path (e.g. the JDK image is copied to a different location
+ // after generating the shared archive), which is acceptable. For most
+ // common cases, the dump time boot path might contain modules_image only.
+ // - The rest of the 'runtime_boot_path' and 'dump_time_boot_path' strings
+ // must be the same.
+ size_t path_sep_len = strlen(os::path_separator());
+ char* rp = strstr(runtime_boot_path, os::path_separator());
+ if (rp != NULL) {
+ rp += path_sep_len;
+ }
+
+ char* dp = strstr((char*)path, os::path_separator());
+ if (dp != NULL) {
+ dp += path_sep_len;
+ }
+
+ if (dp == NULL && rp == NULL) {
+ break; // ok, both runtime and dump time boot paths have modules_images only
+ } else if (dp == NULL && rp != NULL && relaxed_check) {
+ break; // ok, relaxed check, runtime has extra boot append path entries
+ } else if (dp != NULL && rp != NULL) {
+ if (os::file_name_strcmp(dp, rp) == 0) {
+ break; // ok, runtime and dump time paths match
+ }
+ }
+
+ // The paths are different
+ return fail("[BOOT classpath mismatch, actual =",
+ Arguments::get_sysclasspath());
}
break;
case NON_EXIST:
{
struct stat st;
< prev index next >