160 location_symbol = SymbolTable::new_symbol(module_location, CHECK); |
160 location_symbol = SymbolTable::new_symbol(module_location, CHECK); |
161 } |
161 } |
162 } |
162 } |
163 |
163 |
164 |
164 |
165 // Check that the list of packages has no duplicates and that the |
165 // Check that the packages are syntactically ok. |
166 // packages are syntactically ok. |
|
167 GrowableArray<Symbol*>* pkg_list = new GrowableArray<Symbol*>(num_packages); |
166 GrowableArray<Symbol*>* pkg_list = new GrowableArray<Symbol*>(num_packages); |
168 for (int x = 0; x < num_packages; x++) { |
167 for (int x = 0; x < num_packages; x++) { |
169 const char *package_name = packages[x]; |
168 const char *package_name = packages[x]; |
170 if (!Modules::verify_package_name(package_name)) { |
169 if (!Modules::verify_package_name(package_name)) { |
171 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
170 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
172 err_msg("Invalid package name: %s for module: " JAVA_BASE_NAME, package_name)); |
171 err_msg("Invalid package name: %s for module: " JAVA_BASE_NAME, package_name)); |
173 } |
172 } |
174 Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK); |
173 Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK); |
175 // append_if_missing() returns FALSE if entry already exists. |
174 pkg_list->append(pkg_symbol); |
176 if (!pkg_list->append_if_missing(pkg_symbol)) { |
|
177 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
|
178 err_msg("Duplicate package name: %s for module " JAVA_BASE_NAME, |
|
179 package_name)); |
|
180 } |
|
181 } |
175 } |
182 |
176 |
183 // Validate java_base's loader is the boot loader. |
177 // Validate java_base's loader is the boot loader. |
184 oop loader = java_lang_Module::loader(module_handle()); |
178 oop loader = java_lang_Module::loader(module_handle()); |
185 if (loader != NULL) { |
179 if (loader != NULL) { |
186 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
180 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
187 "Class loader must be the boot class loader"); |
181 "Class loader must be the boot class loader"); |
188 } |
182 } |
189 Handle h_loader = Handle(THREAD, loader); |
183 Handle h_loader(THREAD, loader); |
190 |
184 |
191 // Ensure the boot loader's PackageEntryTable has been created |
185 // Ensure the boot loader's PackageEntryTable has been created |
192 PackageEntryTable* package_table = get_package_entry_table(h_loader, CHECK); |
186 PackageEntryTable* package_table = get_package_entry_table(h_loader, CHECK); |
193 assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table"); |
187 assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table"); |
194 |
188 |
244 module_version != NULL ? module_version : "NULL", |
238 module_version != NULL ? module_version : "NULL", |
245 module_location != NULL ? module_location : "NULL", |
239 module_location != NULL ? module_location : "NULL", |
246 pkg_list->length()); |
240 pkg_list->length()); |
247 |
241 |
248 // packages defined to java.base |
242 // packages defined to java.base |
249 for (int x = 0; x < pkg_list->length(); x++) { |
243 if (log_is_enabled(Trace, module)) { |
250 log_trace(module)("define_javabase_module(): creation of package %s for module " JAVA_BASE_NAME, |
244 for (int x = 0; x < pkg_list->length(); x++) { |
251 (pkg_list->at(x))->as_C_string()); |
245 log_trace(module)("define_javabase_module(): creation of package %s for module " JAVA_BASE_NAME, |
|
246 (pkg_list->at(x))->as_C_string()); |
|
247 } |
252 } |
248 } |
253 } |
249 } |
254 |
250 |
255 // Caller needs ResourceMark. |
251 // Caller needs ResourceMark. |
256 void throw_dup_pkg_exception(const char* module_name, PackageEntry* package, TRAPS) { |
252 void throw_dup_pkg_exception(const char* module_name, PackageEntry* package, TRAPS) { |
264 err_msg("Package %s for module %s is already in the unnamed module defined to the class loader", |
260 err_msg("Package %s for module %s is already in the unnamed module defined to the class loader", |
265 package_name, module_name)); |
261 package_name, module_name)); |
266 } |
262 } |
267 } |
263 } |
268 |
264 |
269 void Modules::define_module(jobject module, jstring version, |
265 void Modules::define_module(jobject module, jboolean is_open, jstring version, |
270 jstring location, const char* const* packages, |
266 jstring location, const char* const* packages, |
271 jsize num_packages, TRAPS) { |
267 jsize num_packages, TRAPS) { |
272 ResourceMark rm(THREAD); |
268 ResourceMark rm(THREAD); |
273 |
269 |
274 if (module == NULL) { |
270 if (module == NULL) { |
297 "Module name cannot be null"); |
293 "Module name cannot be null"); |
298 } |
294 } |
299 |
295 |
300 // Special handling of java.base definition |
296 // Special handling of java.base definition |
301 if (strcmp(module_name, JAVA_BASE_NAME) == 0) { |
297 if (strcmp(module_name, JAVA_BASE_NAME) == 0) { |
|
298 assert(is_open == JNI_FALSE, "java.base module cannot be open"); |
302 define_javabase_module(module, version, location, packages, num_packages, CHECK); |
299 define_javabase_module(module, version, location, packages, num_packages, CHECK); |
303 return; |
300 return; |
304 } |
301 } |
305 |
302 |
306 const char* module_version = get_module_version(version); |
303 const char* module_version = get_module_version(version); |
324 package_name, module_name)); |
321 package_name, module_name)); |
325 } |
322 } |
326 |
323 |
327 // Only modules defined to either the boot or platform class loader, can define a "java/" package. |
324 // Only modules defined to either the boot or platform class loader, can define a "java/" package. |
328 if (!h_loader.is_null() && |
325 if (!h_loader.is_null() && |
329 !SystemDictionary::is_platform_class_loader(h_loader) && |
326 !SystemDictionary::is_platform_class_loader(h_loader()) && |
330 (strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0 && |
327 (strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0 && |
331 (package_name[JAVAPKG_LEN] == '/' || package_name[JAVAPKG_LEN] == '\0'))) { |
328 (package_name[JAVAPKG_LEN] == '/' || package_name[JAVAPKG_LEN] == '\0'))) { |
332 const char* class_loader_name = SystemDictionary::loader_name(h_loader()); |
329 const char* class_loader_name = SystemDictionary::loader_name(h_loader()); |
333 size_t pkg_len = strlen(package_name); |
330 size_t pkg_len = strlen(package_name); |
334 char* pkg_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, pkg_len); |
331 char* pkg_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, pkg_len); |
341 jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, pkg_name); |
338 jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, pkg_name); |
342 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message); |
339 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message); |
343 } |
340 } |
344 |
341 |
345 Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK); |
342 Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK); |
346 // append_if_missing() returns FALSE if entry already exists. |
343 pkg_list->append(pkg_symbol); |
347 if (!pkg_list->append_if_missing(pkg_symbol)) { |
|
348 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
|
349 err_msg("Duplicate package name: %s for module %s", |
|
350 package_name, module_name)); |
|
351 } |
|
352 } |
344 } |
353 |
345 |
354 ModuleEntryTable* module_table = get_module_entry_table(h_loader, CHECK); |
346 ModuleEntryTable* module_table = get_module_entry_table(h_loader, CHECK); |
355 assert(module_table != NULL, "module entry table shouldn't be null"); |
347 assert(module_table != NULL, "module entry table shouldn't be null"); |
356 |
348 |
405 } // if (num_packages > 0)... |
397 } // if (num_packages > 0)... |
406 |
398 |
407 // Add the module and its packages. |
399 // Add the module and its packages. |
408 if (!dupl_modules && existing_pkg == NULL) { |
400 if (!dupl_modules && existing_pkg == NULL) { |
409 // Create the entry for this module in the class loader's module entry table. |
401 // Create the entry for this module in the class loader's module entry table. |
410 ModuleEntry* module_entry = module_table->locked_create_entry_or_null(module_handle, module_symbol, |
402 ModuleEntry* module_entry = module_table->locked_create_entry_or_null(module_handle, |
|
403 (is_open == JNI_TRUE), module_symbol, |
411 version_symbol, location_symbol, loader_data); |
404 version_symbol, location_symbol, loader_data); |
412 |
405 |
413 if (module_entry == NULL) { |
406 if (module_entry == NULL) { |
414 dupl_modules = true; |
407 dupl_modules = true; |
415 } else { |
408 } else { |
454 (pkg_list->at(y))->as_C_string(), module_name); |
447 (pkg_list->at(y))->as_C_string(), module_name); |
455 } |
448 } |
456 } |
449 } |
457 |
450 |
458 // If the module is defined to the boot loader and an exploded build is being |
451 // If the module is defined to the boot loader and an exploded build is being |
459 // used, prepend <java.home>/modules/modules_name, if it exists, to the system boot class path. |
452 // used, prepend <java.home>/modules/modules_name to the system boot class path. |
460 if (loader == NULL && |
453 if (loader == NULL && !ClassLoader::has_jrt_entry()) { |
461 !ClassLoader::has_jrt_entry()) { |
|
462 ClassLoader::add_to_exploded_build_list(module_symbol, CHECK); |
454 ClassLoader::add_to_exploded_build_list(module_symbol, CHECK); |
463 } |
455 } |
464 } |
456 } |
465 |
457 |
466 void Modules::set_bootloader_unnamed_module(jobject module, TRAPS) { |
458 void Modules::set_bootloader_unnamed_module(jobject module, TRAPS) { |
486 oop loader = java_lang_Module::loader(module_handle()); |
478 oop loader = java_lang_Module::loader(module_handle()); |
487 if (loader != NULL) { |
479 if (loader != NULL) { |
488 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
480 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
489 "Class loader must be the boot class loader"); |
481 "Class loader must be the boot class loader"); |
490 } |
482 } |
491 Handle h_loader = Handle(THREAD, loader); |
483 Handle h_loader(THREAD, loader); |
492 |
484 |
493 log_debug(module)("set_bootloader_unnamed_module(): recording unnamed module for boot loader"); |
485 log_debug(module)("set_bootloader_unnamed_module(): recording unnamed module for boot loader"); |
494 |
486 |
495 // Ensure the boot loader's PackageEntryTable has been created |
|
496 ModuleEntryTable* module_table = get_module_entry_table(h_loader, CHECK); |
|
497 |
|
498 // Set java.lang.Module for the boot loader's unnamed module |
487 // Set java.lang.Module for the boot loader's unnamed module |
499 ModuleEntry* unnamed_module = module_table->unnamed_module(); |
488 ClassLoaderData* boot_loader_data = ClassLoaderData::the_null_class_loader_data(); |
|
489 ModuleEntry* unnamed_module = boot_loader_data->unnamed_module(); |
500 assert(unnamed_module != NULL, "boot loader's unnamed ModuleEntry not defined"); |
490 assert(unnamed_module != NULL, "boot loader's unnamed ModuleEntry not defined"); |
501 unnamed_module->set_module(ClassLoaderData::the_null_class_loader_data()->add_handle(module_handle)); |
491 unnamed_module->set_module(boot_loader_data->add_handle(module_handle)); |
502 // Store pointer to the ModuleEntry in the unnamed module's java.lang.Module object. |
492 // Store pointer to the ModuleEntry in the unnamed module's java.lang.Module object. |
503 java_lang_Module::set_module_entry(module_handle(), unnamed_module); |
493 java_lang_Module::set_module_entry(module_handle(), unnamed_module); |
504 } |
494 } |
505 |
495 |
506 void Modules::add_module_exports(jobject from_module, const char* package_name, jobject to_module, TRAPS) { |
496 void Modules::add_module_exports(jobject from_module, const char* package_name, jobject to_module, TRAPS) { |
516 if (from_module_entry == NULL) { |
506 if (from_module_entry == NULL) { |
517 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
507 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
518 "from_module cannot be found"); |
508 "from_module cannot be found"); |
519 } |
509 } |
520 |
510 |
521 // All packages in unnamed are exported by default. |
511 // All packages in unnamed and open modules are exported by default. |
522 if (!from_module_entry->is_named()) return; |
512 if (!from_module_entry->is_named() || from_module_entry->is_open()) return; |
523 |
513 |
524 ModuleEntry* to_module_entry; |
514 ModuleEntry* to_module_entry; |
525 if (to_module == NULL) { |
515 if (to_module == NULL) { |
526 to_module_entry = NULL; // It's an unqualified export. |
516 to_module_entry = NULL; // It's an unqualified export. |
527 } else { |
517 } else { |
650 } |
640 } |
651 } |
641 } |
652 |
642 |
653 return JNIHandles::make_local(THREAD, module); |
643 return JNIHandles::make_local(THREAD, module); |
654 } |
644 } |
655 |
|
656 |
|
657 jobject Modules::get_module_by_package_name(jobject loader, const char* package_name, TRAPS) { |
|
658 ResourceMark rm(THREAD); |
|
659 assert(ModuleEntryTable::javabase_defined(), |
|
660 "Attempt to call get_module_from_pkg before " JAVA_BASE_NAME " is defined"); |
|
661 |
|
662 if (package_name == NULL) { |
|
663 THROW_MSG_(vmSymbols::java_lang_NullPointerException(), |
|
664 "package is null", JNI_FALSE); |
|
665 } |
|
666 |
|
667 Handle h_loader (THREAD, JNIHandles::resolve(loader)); |
|
668 // Check that loader is a subclass of java.lang.ClassLoader. |
|
669 if (loader != NULL && !java_lang_ClassLoader::is_subclass(h_loader->klass())) { |
|
670 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), |
|
671 "Class loader is not a subclass of java.lang.ClassLoader", JNI_FALSE); |
|
672 } |
|
673 |
|
674 if (strlen(package_name) == 0) { |
|
675 // Return the unnamed module |
|
676 ModuleEntryTable* module_table = get_module_entry_table(h_loader, CHECK_NULL); |
|
677 if (NULL == module_table) return NULL; |
|
678 const ModuleEntry* const unnamed_module = module_table->unnamed_module(); |
|
679 return JNIHandles::make_local(THREAD, JNIHandles::resolve(unnamed_module->module())); |
|
680 |
|
681 } else { |
|
682 TempNewSymbol package_sym = SymbolTable::new_symbol(package_name, CHECK_NULL); |
|
683 return get_module(package_sym, h_loader, CHECK_NULL); |
|
684 } |
|
685 return NULL; |
|
686 } |
|
687 |
|
688 |
645 |
689 jobject Modules::get_named_module(Handle h_loader, const char* package_name, TRAPS) { |
646 jobject Modules::get_named_module(Handle h_loader, const char* package_name, TRAPS) { |
690 assert(ModuleEntryTable::javabase_defined(), |
647 assert(ModuleEntryTable::javabase_defined(), |
691 "Attempt to call get_named_module before " JAVA_BASE_NAME " is defined"); |
648 "Attempt to call get_named_module before " JAVA_BASE_NAME " is defined"); |
692 assert(h_loader.is_null() || java_lang_ClassLoader::is_subclass(h_loader->klass()), |
649 assert(h_loader.is_null() || java_lang_ClassLoader::is_subclass(h_loader->klass()), |