< prev index next >

src/hotspot/share/cds/aotClassLocation.cpp

Print this page
@@ -45,10 +45,11 @@
  #include "utilities/stringUtils.hpp"
  
  #include <sys/stat.h>
  #include <errno.h>
  
+ Array<ClassPathZipEntry*>* AOTClassLocationConfig::_dumptime_jar_files = nullptr;
  AOTClassLocationConfig* AOTClassLocationConfig::_dumptime_instance = nullptr;
  const AOTClassLocationConfig* AOTClassLocationConfig::_runtime_instance = nullptr;
  
  // A ClassLocationStream represents a list of code locations, which can be iterated using
  // start() and has_next().

@@ -477,10 +478,17 @@
                                                                 tmp_array.length(), CHECK);
    for (int i = 0; i < tmp_array.length(); i++) {
      _class_locations->at_put(i, tmp_array.at(i));
    }
  
+   _dumptime_jar_files = MetadataFactory::new_array<ClassPathZipEntry*>(ClassLoaderData::the_null_class_loader_data(),
+                                                                        tmp_array.length(), CHECK);
+   for (int i = 1; i < tmp_array.length(); i++) {
+     ClassPathZipEntry* jar_file = ClassLoader::create_class_path_zip_entry(tmp_array.at(i)->path());
+     _dumptime_jar_files->at_put(i, jar_file); // may be null if the path is not a valid JAR file
+   }
+ 
    const char* lcp = find_lcp(all_css.boot_and_app_cp(), _dumptime_lcp_len);
    if (_dumptime_lcp_len > 0) {
      os::free((void*)lcp);
      log_info(class, path)("Longest common prefix = %s (%zu chars)", lcp, _dumptime_lcp_len);
    } else {

@@ -638,10 +646,14 @@
  AOTClassLocation const* AOTClassLocationConfig::class_location_at(int index) const {
    return _class_locations->at(index);
  }
  
  int AOTClassLocationConfig::get_module_shared_path_index(Symbol* location) const {
+   if (location == nullptr) {
+     return 0; // Used by java/lang/reflect/Proxy$ProxyBuilder
+   }
+ 
    if (location->starts_with("jrt:", 4)) {
      assert(class_location_at(0)->is_modules_image(), "sanity");
      return 0;
    }
  

@@ -691,10 +703,31 @@
    if (has_nonempty_dir) {
      vm_exit_during_cds_dumping("Cannot have non-empty directory in paths", 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 AOTClassLocationConfig::check_invalid_classpath_index(int classpath_index, InstanceKlass* ik) {
+   if (1 <= classpath_index && classpath_index < length()) {
+     ClassPathZipEntry *zip = _dumptime_jar_files->at(classpath_index);
+     if (zip != nullptr) {
+       JavaThread* current = JavaThread::current();
+       ResourceMark rm(current);
+       const char* const class_name = ik->name()->as_C_string();
+       const char* const file_name = ClassLoader::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);
+       }
+     }
+   }
+ }
+ 
  AOTClassLocationConfig* AOTClassLocationConfig::write_to_archive() const {
    Array<AOTClassLocation*>* archived_copy = ArchiveBuilder::new_ro_array<AOTClassLocation*>(_class_locations->length());
    for (int i = 0; i < _class_locations->length(); i++) {
      archived_copy->at_put(i, _class_locations->at(i)->write_to_archive());
      ArchivePtrMarker::mark_pointer((address*)archived_copy->adr_at(i));
< prev index next >