83 trace_class_path("app loader class path (skipped)=", app_class_path);
84 } else {
85 trace_class_path("app loader class path=", app_class_path);
86 ClassLoader::setup_app_search_path(current, app_class_path);
87 }
88
89 os::free(app_class_path);
90 }
91
92 void ClassLoaderExt::process_module_table(JavaThread* current, ModuleEntryTable* met) {
93 ResourceMark rm(current);
94 GrowableArray<char*>* module_paths = new GrowableArray<char*>(5);
95
96 class ModulePathsGatherer : public ModuleClosure {
97 JavaThread* _current;
98 GrowableArray<char*>* _module_paths;
99 public:
100 ModulePathsGatherer(JavaThread* current, GrowableArray<char*>* module_paths) :
101 _current(current), _module_paths(module_paths) {}
102 void do_module(ModuleEntry* m) {
103 char* path = m->location()->as_C_string();
104 if (strncmp(path, "file:", 5) == 0) {
105 path = ClassLoader::skip_uri_protocol(path);
106 char* path_copy = NEW_RESOURCE_ARRAY(char, strlen(path) + 1);
107 strcpy(path_copy, path);
108 _module_paths->append(path_copy);
109 }
110 }
111 };
112
113 ModulePathsGatherer gatherer(current, module_paths);
114 {
115 MutexLocker ml(Module_lock);
116 met->modules_do(&gatherer);
117 }
118
119 for (int i = 0; i < module_paths->length(); i++) {
120 ClassLoader::setup_module_search_path(current, module_paths->at(i));
121 }
122 }
275 }
276 result->set_shared_classpath_index(classpath_index);
277 result->set_shared_class_loader_type(classloader_type);
278 #if INCLUDE_CDS_JAVA_HEAP
279 if (CDSConfig::is_dumping_heap() && AllowArchivingWithJavaAgent && classloader_type == ClassLoader::BOOT_LOADER &&
280 classpath_index < 0 && redefined) {
281 // When dumping the heap (which happens only during static dump), classes for the built-in
282 // loaders are always loaded from known locations (jimage, classpath or modulepath),
283 // so classpath_index should always be >= 0.
284 // The only exception is when a java agent is used during dump time (for testing
285 // purposes only). If a class is transformed by the agent, the CodeSource of
286 // this class may point to an unknown location. This may break heap object archiving,
287 // which requires all the boot classes to be from known locations. This is an
288 // uncommon scenario (even in test cases). Let's simply disable heap object archiving.
289 ResourceMark rm;
290 log_warning(cds)("CDS heap objects cannot be written because class %s maybe modified by ClassFileLoadHook.",
291 result->external_name());
292 HeapShared::disable_writing();
293 }
294 #endif // INCLUDE_CDS_JAVA_HEAP
295 }
|
83 trace_class_path("app loader class path (skipped)=", app_class_path);
84 } else {
85 trace_class_path("app loader class path=", app_class_path);
86 ClassLoader::setup_app_search_path(current, app_class_path);
87 }
88
89 os::free(app_class_path);
90 }
91
92 void ClassLoaderExt::process_module_table(JavaThread* current, ModuleEntryTable* met) {
93 ResourceMark rm(current);
94 GrowableArray<char*>* module_paths = new GrowableArray<char*>(5);
95
96 class ModulePathsGatherer : public ModuleClosure {
97 JavaThread* _current;
98 GrowableArray<char*>* _module_paths;
99 public:
100 ModulePathsGatherer(JavaThread* current, GrowableArray<char*>* module_paths) :
101 _current(current), _module_paths(module_paths) {}
102 void do_module(ModuleEntry* m) {
103 if (m->location() == nullptr) {
104 // This is a dynamic generated module (which we loaded from the static archive) for supporting
105 // dynamic proxies. We don't archive any other such modules.
106 // No need to include such modules in _module_path.
107 assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
108 assert(Modules::is_dynamic_proxy_module(m), "must be");
109 if (log_is_enabled(Info, cds, dynamic, proxy)) {
110 ResourceMark rm;
111 log_info(cds, dynamic, proxy)("Archived dynamic module: %s", m->name()->as_C_string());
112 }
113 return;
114 }
115 char* path = m->location()->as_C_string();
116 if (strncmp(path, "file:", 5) == 0) {
117 path = ClassLoader::skip_uri_protocol(path);
118 char* path_copy = NEW_RESOURCE_ARRAY(char, strlen(path) + 1);
119 strcpy(path_copy, path);
120 _module_paths->append(path_copy);
121 }
122 }
123 };
124
125 ModulePathsGatherer gatherer(current, module_paths);
126 {
127 MutexLocker ml(Module_lock);
128 met->modules_do(&gatherer);
129 }
130
131 for (int i = 0; i < module_paths->length(); i++) {
132 ClassLoader::setup_module_search_path(current, module_paths->at(i));
133 }
134 }
287 }
288 result->set_shared_classpath_index(classpath_index);
289 result->set_shared_class_loader_type(classloader_type);
290 #if INCLUDE_CDS_JAVA_HEAP
291 if (CDSConfig::is_dumping_heap() && AllowArchivingWithJavaAgent && classloader_type == ClassLoader::BOOT_LOADER &&
292 classpath_index < 0 && redefined) {
293 // When dumping the heap (which happens only during static dump), classes for the built-in
294 // loaders are always loaded from known locations (jimage, classpath or modulepath),
295 // so classpath_index should always be >= 0.
296 // The only exception is when a java agent is used during dump time (for testing
297 // purposes only). If a class is transformed by the agent, the CodeSource of
298 // this class may point to an unknown location. This may break heap object archiving,
299 // which requires all the boot classes to be from known locations. This is an
300 // uncommon scenario (even in test cases). Let's simply disable heap object archiving.
301 ResourceMark rm;
302 log_warning(cds)("CDS heap objects cannot be written because class %s maybe modified by ClassFileLoadHook.",
303 result->external_name());
304 HeapShared::disable_writing();
305 }
306 #endif // INCLUDE_CDS_JAVA_HEAP
307 if (CDSConfig::is_dumping_preimage_static_archive() || CDSConfig::is_dumping_dynamic_archive()) {
308 check_invalid_classpath_index(classpath_index, result);
309 }
310 }
311
312 ClassPathEntry* ClassLoaderExt::get_class_path_entry(s2 classpath_index) {
313 if (classpath_index < 0) {
314 return nullptr;
315 }
316
317 if (classpath_index == 0) {
318 assert(has_jrt_entry(), "CDS requires modules image");
319 return get_jrt_entry();
320 }
321
322 // Iterate over -Xbootclasspath, if any;
323 int i = 0;
324 for (ClassPathEntry* cpe = first_append_entry(); cpe != nullptr; cpe = cpe->next()) {
325 i++;
326 if (i == classpath_index) {
327 return cpe;
328 }
329 }
330
331 // Iterate over -cp, if any
332 for (ClassPathEntry* cpe = app_classpath_entries(); cpe != nullptr; cpe = cpe->next()) {
333 i++;
334 if (i == classpath_index) {
335 return cpe;
336 }
337 }
338
339 // Iterate over --module-path, if any
340 for (ClassPathEntry* cpe = module_path_entries(); cpe != nullptr; cpe = cpe->next()) {
341 i++;
342 if (i == classpath_index) {
343 return cpe;
344 }
345 }
346
347 return nullptr;
348 }
349
350 // It's possible to use reflection+setAccessible to call into ClassLoader::defineClass() to
351 // pretend that a dynamically generated class comes from a JAR file in the classpath.
352 // Detect such classes and exclude them from the archive.
353 void ClassLoaderExt::check_invalid_classpath_index(s2 classpath_index, InstanceKlass* ik) {
354 ClassPathEntry *cpe = get_class_path_entry(classpath_index);
355 if (cpe != nullptr && cpe->is_jar_file()) {
356 ClassPathZipEntry *zip = (ClassPathZipEntry*)cpe;
357 JavaThread* current = JavaThread::current();
358 ResourceMark rm(current);
359 const char* const class_name = ik->name()->as_C_string();
360 const char* const file_name = file_name_for_class_name(class_name,
361 ik->name()->utf8_length());
362 if (!zip->has_entry(current, file_name)) {
363 log_warning(cds)("class %s cannot be archived because it was not define from %s as claimed",
364 class_name, zip->name());
365 ik->set_shared_classpath_index(-1);
366 }
367 }
368 }
|