< prev index next >

src/hotspot/share/classfile/classLoaderExt.cpp

Print this page
*** 57,10 ***
--- 57,11 ---
  jshort ClassLoaderExt::_max_used_path_index = 0;
  int ClassLoaderExt::_num_module_paths = 0;
  bool ClassLoaderExt::_has_app_classes = false;
  bool ClassLoaderExt::_has_platform_classes = false;
  bool ClassLoaderExt::_has_non_jar_in_classpath = false;
+ int ClassLoaderExt::_app_class_exclusion_start_path_index = INT_MAX;
  
  void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) {
    if (CDSConfig::is_using_archive()) {
      warning("Sharing is only supported for boot loader classes because bootstrap classpath has been appended");
      FileMapInfo::current_info()->set_has_platform_or_app_classes(false);

*** 103,10 ***
--- 104,22 ---
      GrowableArray<const char*>* _module_paths;
     public:
      ModulePathsGatherer(JavaThread* current, GrowableArray<const char*>* module_paths) :
        _current(current), _module_paths(module_paths) {}
      void do_module(ModuleEntry* m) {
+       if (m->location() == nullptr) {
+         // This is a dynamic generated module (which we loaded from the static archive) for supporting
+         // dynamic proxies. We don't archive any other such modules.
+         // No need to include such modules in _module_path.
+         assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
+         assert(Modules::is_dynamic_proxy_module(m), "must be");
+         if (log_is_enabled(Info, cds, dynamic, proxy)) {
+           ResourceMark rm;
+           log_info(cds, dynamic, proxy)("Archived dynamic module: %s", m->name()->as_C_string());
+         }
+         return;
+       }
        char* uri = m->location()->as_C_string();
        if (strncmp(uri, "file:", 5) == 0) {
          char* path = ClassLoader::uri_to_path(uri);
          extract_jar_files_from_path(path, _module_paths);
        }

*** 338,6 ***
--- 351,78 ---
      log_warning(cds)("CDS heap objects cannot be written because class %s maybe modified by ClassFileLoadHook.",
                       result->external_name());
      HeapShared::disable_writing();
    }
  #endif // INCLUDE_CDS_JAVA_HEAP
+   if (CDSConfig::is_dumping_preimage_static_archive() || CDSConfig::is_dumping_dynamic_archive()) {
+     check_invalid_classpath_index(classpath_index, result);
+   }
  }
+ 
+ ClassPathEntry* ClassLoaderExt::get_class_path_entry(s2 classpath_index) {
+   if (classpath_index < 0) {
+     return nullptr;
+   }
+ 
+   if (classpath_index == 0) {
+     assert(has_jrt_entry(), "CDS requires modules image");
+     return get_jrt_entry();
+   }
+ 
+   // Iterate over -Xbootclasspath, if any;
+   int i = 0;
+   for (ClassPathEntry* cpe = first_append_entry(); cpe != nullptr; cpe = cpe->next()) {
+     i++;
+     if (i == classpath_index) {
+       return cpe;
+     }
+   }
+ 
+   // Iterate over -cp, if any
+   for (ClassPathEntry* cpe = app_classpath_entries(); cpe != nullptr; cpe = cpe->next()) {
+     i++;
+     if (i == classpath_index) {
+       return cpe;
+     }
+   }
+ 
+   // Iterate over --module-path, if any
+   for (ClassPathEntry* cpe = module_path_entries(); cpe != nullptr; cpe = cpe->next()) {
+     i++;
+     if (i == classpath_index) {
+       return cpe;
+     }
+   }
+ 
+   return nullptr;
+ }
+ 
+ // It's possible to use reflection+setAccessible to call into ClassLoader::defineClass() to
+ // pretend that a dynamically generated class comes from a JAR file in the classpath.
+ // Detect such classes and exclude them from the archive.
+ void ClassLoaderExt::check_invalid_classpath_index(s2 classpath_index, InstanceKlass* ik) {
+   ClassPathEntry *cpe = get_class_path_entry(classpath_index);
+   if (cpe != nullptr && cpe->is_jar_file()) {
+     ClassPathZipEntry *zip = (ClassPathZipEntry*)cpe;
+     JavaThread* current = JavaThread::current();
+     ResourceMark rm(current);
+     const char* const class_name = ik->name()->as_C_string();
+     const char* const file_name = file_name_for_class_name(class_name,
+                                                            ik->name()->utf8_length());
+     if (!zip->has_entry(current, file_name)) {
+       log_warning(cds)("class %s cannot be archived because it was not define from %s as claimed",
+                        class_name, zip->name());
+       ik->set_shared_classpath_index(-1);
+     }
+   }
+ }
+ 
+ // -XX:CacheOnlyClassesIn=
+ bool ClassLoaderExt::should_be_excluded(InstanceKlass* k) {
+   int path_index = k->shared_classpath_index();
+   if (path_index >= _app_class_exclusion_start_path_index  && path_index < _app_module_paths_start_index) {
+     return true;
+   } else {
+     return false;
+   }
+ }
+ 
< prev index next >