28 #include "classfile/classLoader.inline.hpp" |
28 #include "classfile/classLoader.inline.hpp" |
29 #include "classfile/classLoaderExt.hpp" |
29 #include "classfile/classLoaderExt.hpp" |
30 #include "classfile/classLoaderData.inline.hpp" |
30 #include "classfile/classLoaderData.inline.hpp" |
31 #include "classfile/klassFactory.hpp" |
31 #include "classfile/klassFactory.hpp" |
32 #include "classfile/modules.hpp" |
32 #include "classfile/modules.hpp" |
33 #include "classfile/sharedPathsMiscInfo.hpp" |
|
34 #include "classfile/systemDictionaryShared.hpp" |
33 #include "classfile/systemDictionaryShared.hpp" |
35 #include "classfile/vmSymbols.hpp" |
34 #include "classfile/vmSymbols.hpp" |
|
35 #include "logging/log.hpp" |
36 #include "memory/allocation.inline.hpp" |
36 #include "memory/allocation.inline.hpp" |
37 #include "memory/filemap.hpp" |
37 #include "memory/filemap.hpp" |
38 #include "memory/resourceArea.hpp" |
38 #include "memory/resourceArea.hpp" |
39 #include "oops/instanceKlass.hpp" |
39 #include "oops/instanceKlass.hpp" |
40 #include "oops/oop.inline.hpp" |
40 #include "oops/oop.inline.hpp" |
54 bool ClassLoaderExt::_has_platform_classes = false; |
54 bool ClassLoaderExt::_has_platform_classes = false; |
55 |
55 |
56 void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) { |
56 void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) { |
57 if (UseSharedSpaces) { |
57 if (UseSharedSpaces) { |
58 warning("Sharing is only supported for boot loader classes because bootstrap classpath has been appended"); |
58 warning("Sharing is only supported for boot loader classes because bootstrap classpath has been appended"); |
59 FileMapInfo::current_info()->header()->set_has_platform_or_app_classes(false); |
59 FileMapInfo::current_info()->set_has_platform_or_app_classes(false); |
60 } |
60 } |
61 ClassLoader::add_to_boot_append_entries(new_entry); |
61 ClassLoader::add_to_boot_append_entries(new_entry); |
62 } |
62 } |
63 |
63 |
64 void ClassLoaderExt::setup_app_search_path() { |
64 void ClassLoaderExt::setup_app_search_path() { |
65 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, |
65 Arguments::assert_is_dumping_archive(); |
66 "this function is only used at CDS dump time"); |
|
67 _app_class_paths_start_index = ClassLoader::num_boot_classpath_entries(); |
66 _app_class_paths_start_index = ClassLoader::num_boot_classpath_entries(); |
68 char* app_class_path = os::strdup(Arguments::get_appclasspath()); |
67 char* app_class_path = os::strdup(Arguments::get_appclasspath()); |
69 |
68 |
70 if (strcmp(app_class_path, ".") == 0) { |
69 if (strcmp(app_class_path, ".") == 0) { |
71 // This doesn't make any sense, even for AppCDS, so let's skip it. We |
70 // This doesn't make any sense, even for AppCDS, so let's skip it. We |
72 // don't want to throw an error here because -cp "." is usually assigned |
71 // don't want to throw an error here because -cp "." is usually assigned |
73 // by the launcher when classpath is not specified. |
72 // by the launcher when classpath is not specified. |
74 trace_class_path("app loader class path (skipped)=", app_class_path); |
73 trace_class_path("app loader class path (skipped)=", app_class_path); |
75 } else { |
74 } else { |
76 trace_class_path("app loader class path=", app_class_path); |
75 trace_class_path("app loader class path=", app_class_path); |
77 shared_paths_misc_info()->add_app_classpath(app_class_path); |
|
78 ClassLoader::setup_app_search_path(app_class_path); |
76 ClassLoader::setup_app_search_path(app_class_path); |
79 } |
77 } |
80 } |
78 } |
81 |
79 |
82 void ClassLoaderExt::process_module_table(ModuleEntryTable* met, TRAPS) { |
80 void ClassLoaderExt::process_module_table(ModuleEntryTable* met, TRAPS) { |
91 m = m->next(); |
89 m = m->next(); |
92 } |
90 } |
93 } |
91 } |
94 } |
92 } |
95 void ClassLoaderExt::setup_module_paths(TRAPS) { |
93 void ClassLoaderExt::setup_module_paths(TRAPS) { |
96 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, |
94 Arguments::assert_is_dumping_archive(); |
97 "this function is only used with CDS dump time"); |
|
98 _app_module_paths_start_index = ClassLoader::num_boot_classpath_entries() + |
95 _app_module_paths_start_index = ClassLoader::num_boot_classpath_entries() + |
99 ClassLoader::num_app_classpath_entries(); |
96 ClassLoader::num_app_classpath_entries(); |
100 Handle system_class_loader (THREAD, SystemDictionary::java_system_loader()); |
97 Handle system_class_loader (THREAD, SystemDictionary::java_system_loader()); |
101 ModuleEntryTable* met = Modules::get_module_entry_table(system_class_loader); |
98 ModuleEntryTable* met = Modules::get_module_entry_table(system_class_loader); |
102 process_module_table(met, THREAD); |
99 process_module_table(met, THREAD); |
146 } |
143 } |
147 if (strncmp(tag, line_start, tag_len) == 0) { |
144 if (strncmp(tag, line_start, tag_len) == 0) { |
148 if (found != NULL) { |
145 if (found != NULL) { |
149 // Same behavior as jdk/src/share/classes/java/util/jar/Attributes.java |
146 // Same behavior as jdk/src/share/classes/java/util/jar/Attributes.java |
150 // If duplicated entries are found, the last one is used. |
147 // If duplicated entries are found, the last one is used. |
151 tty->print_cr("Warning: Duplicate name in Manifest: %s.\n" |
148 log_warning(cds)("Warning: Duplicate name in Manifest: %s.\n" |
152 "Ensure that the manifest does not have duplicate entries, and\n" |
149 "Ensure that the manifest does not have duplicate entries, and\n" |
153 "that blank lines separate individual sections in both your\n" |
150 "that blank lines separate individual sections in both your\n" |
154 "manifest and in the META-INF/MANIFEST.MF entry in the jar file:\n%s\n", tag, jar_path); |
151 "manifest and in the META-INF/MANIFEST.MF entry in the jar file:\n%s\n", tag, jar_path); |
155 } |
152 } |
156 found = line_start + tag_len; |
153 found = line_start + tag_len; |
210 ResourceMark rm(THREAD); |
207 ResourceMark rm(THREAD); |
211 size_t libname_len = dir_len + name_len; |
208 size_t libname_len = dir_len + name_len; |
212 char* libname = NEW_RESOURCE_ARRAY(char, libname_len + 1); |
209 char* libname = NEW_RESOURCE_ARRAY(char, libname_len + 1); |
213 int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start); |
210 int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start); |
214 assert((size_t)n == libname_len, "Unexpected number of characters in string"); |
211 assert((size_t)n == libname_len, "Unexpected number of characters in string"); |
215 trace_class_path("library = ", libname); |
212 if (ClassLoader::update_class_path_entry_list(libname, true, false, true /* from_class_path_attr */)) { |
216 ClassLoader::update_class_path_entry_list(libname, true, false); |
213 trace_class_path("library = ", libname); |
|
214 } else { |
|
215 trace_class_path("library (non-existent) = ", libname); |
|
216 FileMapInfo::record_non_existent_class_path_entry(libname); |
|
217 } |
217 } |
218 } |
218 |
219 |
219 file_start = file_end; |
220 file_start = file_end; |
220 } |
221 } |
221 } |
222 } |
222 } |
223 } |
223 |
224 |
224 void ClassLoaderExt::setup_search_paths() { |
225 void ClassLoaderExt::setup_search_paths() { |
225 shared_paths_misc_info()->record_app_offset(); |
|
226 ClassLoaderExt::setup_app_search_path(); |
226 ClassLoaderExt::setup_app_search_path(); |
227 } |
227 } |
228 |
228 |
229 void ClassLoaderExt::record_result(const s2 classpath_index, |
229 void ClassLoaderExt::record_result(const s2 classpath_index, |
230 InstanceKlass* result, |
230 InstanceKlass* result, |
231 TRAPS) { |
231 TRAPS) { |
232 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity"); |
232 Arguments::assert_is_dumping_archive(); |
233 |
233 |
234 // We need to remember where the class comes from during dumping. |
234 // We need to remember where the class comes from during dumping. |
235 oop loader = result->class_loader(); |
235 oop loader = result->class_loader(); |
236 s2 classloader_type = ClassLoader::BOOT_LOADER; |
236 s2 classloader_type = ClassLoader::BOOT_LOADER; |
237 if (SystemDictionary::is_system_class_loader(loader)) { |
237 if (SystemDictionary::is_system_class_loader(loader)) { |
246 } |
246 } |
247 result->set_shared_classpath_index(classpath_index); |
247 result->set_shared_classpath_index(classpath_index); |
248 result->set_class_loader_type(classloader_type); |
248 result->set_class_loader_type(classloader_type); |
249 } |
249 } |
250 |
250 |
251 void ClassLoaderExt::finalize_shared_paths_misc_info() { |
|
252 if (!_has_app_classes) { |
|
253 shared_paths_misc_info()->pop_app(); |
|
254 } |
|
255 } |
|
256 |
|
257 // Load the class of the given name from the location given by path. The path is specified by |
251 // Load the class of the given name from the location given by path. The path is specified by |
258 // the "source:" in the class list file (see classListParser.cpp), and can be a directory or |
252 // the "source:" in the class list file (see classListParser.cpp), and can be a directory or |
259 // a JAR file. |
253 // a JAR file. |
260 InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS) { |
254 InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS) { |
261 assert(name != NULL, "invariant"); |
255 assert(name != NULL, "invariant"); |
279 PerfClassTraceTime::CLASS_LOAD); |
273 PerfClassTraceTime::CLASS_LOAD); |
280 stream = e->open_stream(file_name, CHECK_NULL); |
274 stream = e->open_stream(file_name, CHECK_NULL); |
281 } |
275 } |
282 |
276 |
283 if (NULL == stream) { |
277 if (NULL == stream) { |
284 tty->print_cr("Preload Warning: Cannot find %s", class_name); |
278 log_warning(cds)("Preload Warning: Cannot find %s", class_name); |
285 return NULL; |
279 return NULL; |
286 } |
280 } |
287 |
281 |
288 assert(stream != NULL, "invariant"); |
282 assert(stream != NULL, "invariant"); |
289 stream->set_verify(true); |
283 stream->set_verify(true); |
337 // File or directory not found |
331 // File or directory not found |
338 return NULL; |
332 return NULL; |
339 } |
333 } |
340 ClassPathEntry* new_entry = NULL; |
334 ClassPathEntry* new_entry = NULL; |
341 |
335 |
342 new_entry = create_class_path_entry(path, &st, false, false, CHECK_NULL); |
336 new_entry = create_class_path_entry(path, &st, false, false, false, CHECK_NULL); |
343 if (new_entry == NULL) { |
337 if (new_entry == NULL) { |
344 return NULL; |
338 return NULL; |
345 } |
339 } |
346 ccpe._path = strdup(path); |
340 ccpe._path = strdup(path); |
347 ccpe._entry = new_entry; |
341 ccpe._entry = new_entry; |