151 152 // helper routines 153 bool string_starts_with(const char* str, const char* str_to_find) { 154 size_t str_len = strlen(str); 155 size_t str_to_find_len = strlen(str_to_find); 156 if (str_to_find_len > str_len) { 157 return false; 158 } 159 return (strncmp(str, str_to_find, str_to_find_len) == 0); 160 } 161 162 static const char* get_jimage_version_string() { 163 static char version_string[10] = ""; 164 if (version_string[0] == '\0') { 165 jio_snprintf(version_string, sizeof(version_string), "%d.%d", 166 VM_Version::vm_major_version(), VM_Version::vm_minor_version()); 167 } 168 return (const char*)version_string; 169 } 170 171 bool ClassLoader::string_ends_with(const char* str, const char* str_to_find) { 172 size_t str_len = strlen(str); 173 size_t str_to_find_len = strlen(str_to_find); 174 if (str_to_find_len > str_len) { 175 return false; 176 } 177 return (strncmp(str + (str_len - str_to_find_len), str_to_find, str_to_find_len) == 0); 178 } 179 180 // Used to obtain the package name from a fully qualified class name. 181 // It is the responsibility of the caller to establish a ResourceMark. 182 const char* ClassLoader::package_from_name(const char* const class_name, bool* bad_class_name) { 183 if (class_name == NULL) { 184 if (bad_class_name != NULL) { 185 *bad_class_name = true; 186 } 187 return NULL; 188 } 189 190 if (bad_class_name != NULL) { 544 setup_boot_search_path(sys_class_path); 545 } 546 547 #if INCLUDE_CDS 548 int ClassLoader::get_shared_paths_misc_info_size() { 549 return _shared_paths_misc_info->get_used_bytes(); 550 } 551 552 void* ClassLoader::get_shared_paths_misc_info() { 553 return _shared_paths_misc_info->buffer(); 554 } 555 556 bool ClassLoader::check_shared_paths_misc_info(void *buf, int size, bool is_static) { 557 SharedPathsMiscInfo* checker = new SharedPathsMiscInfo((char*)buf, size); 558 bool result = checker->check(is_static); 559 delete checker; 560 return result; 561 } 562 563 void ClassLoader::setup_app_search_path(const char *class_path) { 564 565 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity"); 566 567 Thread* THREAD = Thread::current(); 568 int len = (int)strlen(class_path); 569 int end = 0; 570 571 // Iterate over class path entries 572 for (int start = 0; start < len; start = end) { 573 while (class_path[end] && class_path[end] != os::path_separator()[0]) { 574 end++; 575 } 576 EXCEPTION_MARK; 577 ResourceMark rm(THREAD); 578 char* path = NEW_RESOURCE_ARRAY(char, end - start + 1); 579 strncpy(path, &class_path[start], end - start); 580 path[end - start] = '\0'; 581 582 update_class_path_entry_list(path, false, false, false); 583 584 while (class_path[end] == os::path_separator()[0]) { 585 end++; 586 } 587 } 588 } 589 590 void ClassLoader::add_to_module_path_entries(const char* path, 591 ClassPathEntry* entry) { 592 assert(entry != NULL, "ClassPathEntry should not be NULL"); 593 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only"); 594 595 // The entry does not exist, add to the list 596 if (_module_path_entries == NULL) { 597 assert(_last_module_path_entry == NULL, "Sanity"); 598 _module_path_entries = _last_module_path_entry = entry; 599 } else { 600 _last_module_path_entry->set_next(entry); 601 _last_module_path_entry = entry; 602 } 603 } 604 605 // Add a module path to the _module_path_entries list. 606 void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) { 626 void ClassLoader::setup_module_search_path(const char* path, TRAPS) { 627 update_module_path_entry_list(path, THREAD); 628 } 629 630 #endif // INCLUDE_CDS 631 632 void ClassLoader::close_jrt_image() { 633 // Not applicable for exploded builds 634 if (!ClassLoader::has_jrt_entry()) return; 635 _jrt_entry->close_jimage(); 636 } 637 638 // Construct the array of module/path pairs as specified to --patch-module 639 // for the boot loader to search ahead of the jimage, if the class being 640 // loaded is defined to a module that has been specified to --patch-module. 641 void ClassLoader::setup_patch_mod_entries() { 642 Thread* THREAD = Thread::current(); 643 GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix(); 644 int num_of_entries = patch_mod_args->length(); 645 646 647 // Set up the boot loader's _patch_mod_entries list 648 _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true); 649 650 for (int i = 0; i < num_of_entries; i++) { 651 const char* module_name = (patch_mod_args->at(i))->module_name(); 652 Symbol* const module_sym = SymbolTable::new_symbol(module_name); 653 assert(module_sym != NULL, "Failed to obtain Symbol for module name"); 654 ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym); 655 656 char* class_path = (patch_mod_args->at(i))->path_string(); 657 int len = (int)strlen(class_path); 658 int end = 0; 659 // Iterate over the module's class path entries 660 for (int start = 0; start < len; start = end) { 661 while (class_path[end] && class_path[end] != os::path_separator()[0]) { 662 end++; 663 } 664 EXCEPTION_MARK; 665 ResourceMark rm(THREAD); 666 char* path = NEW_RESOURCE_ARRAY(char, end - start + 1); 667 strncpy(path, &class_path[start], end - start); 668 path[end - start] = '\0'; 669 670 struct stat st; 671 if (os::stat(path, &st) == 0) { 672 // File or directory found 673 ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK); 674 // If the path specification is valid, enter it into this module's list 675 if (new_entry != NULL) { 676 module_cpl->add_to_list(new_entry); 677 } 678 } 679 680 while (class_path[end] == os::path_separator()[0]) { 681 end++; 682 } 683 } 684 685 // Record the module into the list of --patch-module entries only if 686 // valid ClassPathEntrys have been created 687 if (module_cpl->module_first_entry() != NULL) { 688 _patch_mod_entries->push(module_cpl); 689 } 690 } 691 } 692 693 // Determine whether the module has been patched via the command-line 694 // option --patch-module 695 bool ClassLoader::is_in_patch_mod_entries(Symbol* module_name) { 696 if (_patch_mod_entries != NULL && _patch_mod_entries->is_nonempty()) { 697 int table_len = _patch_mod_entries->length(); 698 for (int i = 0; i < table_len; i++) { 699 ModuleClassPathList* patch_mod = _patch_mod_entries->at(i); 700 if (module_name->fast_compare(patch_mod->module_name()) == 0) { 701 return true; 702 } 703 } 704 } 705 return false; 706 } 707 708 // Set up the _jrt_entry if present and boot append path 709 void ClassLoader::setup_boot_search_path(const char *class_path) { 710 int len = (int)strlen(class_path); 711 int end = 0; 712 bool set_base_piece = true; 713 714 #if INCLUDE_CDS 715 if (DumpSharedSpaces || DynamicDumpSharedSpaces) { 716 if (!Arguments::has_jimage()) { 717 vm_exit_during_initialization("CDS is not supported in exploded JDK build", NULL); 718 } 719 } 720 #endif 721 722 // Iterate over class path entries 723 for (int start = 0; start < len; start = end) { 724 while (class_path[end] && class_path[end] != os::path_separator()[0]) { 725 end++; 726 } 727 EXCEPTION_MARK; 728 ResourceMark rm(THREAD); 729 char* path = NEW_RESOURCE_ARRAY(char, end - start + 1); 730 strncpy(path, &class_path[start], end - start); 731 path[end - start] = '\0'; 732 733 if (set_base_piece) { 734 // The first time through the bootstrap_search setup, it must be determined 735 // what the base or core piece of the boot loader search is. Either a java runtime 736 // image is present or this is an exploded module build situation. 737 assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, JAVA_BASE_NAME), 738 "Incorrect boot loader search path, no java runtime image or " JAVA_BASE_NAME " exploded build"); 739 struct stat st; 740 if (os::stat(path, &st) == 0) { 741 // Directory found 742 ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK); 743 744 // Check for a jimage 745 if (Arguments::has_jimage()) { 746 assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice"); 747 _jrt_entry = new_entry; 748 assert(new_entry != NULL && new_entry->is_modules_image(), "No java runtime image present"); 749 assert(_jrt_entry->jimage() != NULL, "No java runtime image"); 750 } 751 } else { 752 // If path does not exist, exit 753 vm_exit_during_initialization("Unable to establish the boot loader search path", path); 754 } 755 set_base_piece = false; 756 } else { 757 // Every entry on the system boot class path after the initial base piece, 758 // which is set by os::set_boot_path(), is considered an appended entry. 759 update_class_path_entry_list(path, false, true, false); 760 } 761 762 while (class_path[end] == os::path_separator()[0]) { 763 end++; 764 } 765 } 766 } 767 768 // During an exploded modules build, each module defined to the boot loader 769 // will be added to the ClassLoader::_exploded_entries array. 770 void ClassLoader::add_to_exploded_build_list(Symbol* module_sym, TRAPS) { 771 assert(!ClassLoader::has_jrt_entry(), "Exploded build not applicable"); 772 assert(_exploded_entries != NULL, "_exploded_entries was not initialized"); 773 774 // Find the module's symbol 775 ResourceMark rm(THREAD); 776 const char *module_name = module_sym->as_C_string(); 777 const char *home = Arguments::get_java_home(); 778 const char file_sep = os::file_separator()[0]; 779 // 10 represents the length of "modules" + 2 file separators + \0 780 size_t len = strlen(home) + strlen(module_name) + 10; 781 char *path = NEW_RESOURCE_ARRAY(char, len); 782 jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name); 783 | 151 152 // helper routines 153 bool string_starts_with(const char* str, const char* str_to_find) { 154 size_t str_len = strlen(str); 155 size_t str_to_find_len = strlen(str_to_find); 156 if (str_to_find_len > str_len) { 157 return false; 158 } 159 return (strncmp(str, str_to_find, str_to_find_len) == 0); 160 } 161 162 static const char* get_jimage_version_string() { 163 static char version_string[10] = ""; 164 if (version_string[0] == '\0') { 165 jio_snprintf(version_string, sizeof(version_string), "%d.%d", 166 VM_Version::vm_major_version(), VM_Version::vm_minor_version()); 167 } 168 return (const char*)version_string; 169 } 170 171 class ClasspathStream : public StackObj { 172 const char* _class_path; 173 int _len; 174 int _start; 175 int _end; 176 177 public: 178 ClasspathStream(const char* class_path) { 179 _class_path = class_path; 180 _len = (int)strlen(class_path); 181 _start = 0; 182 _end = 0; 183 } 184 185 bool has_next() { 186 return _start < _len; 187 } 188 189 const char* get_next() { 190 while (_class_path[_end] && _class_path[_end] != os::path_separator()[0]) { 191 _end++; 192 } 193 int path_len = _end - _start; 194 char* path = NEW_RESOURCE_ARRAY(char, path_len + 1); 195 strncpy(path, &_class_path[_start], path_len); 196 path[path_len] = '\0'; 197 198 while (_class_path[_end] == os::path_separator()[0]) { 199 _end++; 200 } 201 _start = _end; 202 return path; 203 } 204 }; 205 206 bool ClassLoader::string_ends_with(const char* str, const char* str_to_find) { 207 size_t str_len = strlen(str); 208 size_t str_to_find_len = strlen(str_to_find); 209 if (str_to_find_len > str_len) { 210 return false; 211 } 212 return (strncmp(str + (str_len - str_to_find_len), str_to_find, str_to_find_len) == 0); 213 } 214 215 // Used to obtain the package name from a fully qualified class name. 216 // It is the responsibility of the caller to establish a ResourceMark. 217 const char* ClassLoader::package_from_name(const char* const class_name, bool* bad_class_name) { 218 if (class_name == NULL) { 219 if (bad_class_name != NULL) { 220 *bad_class_name = true; 221 } 222 return NULL; 223 } 224 225 if (bad_class_name != NULL) { 579 setup_boot_search_path(sys_class_path); 580 } 581 582 #if INCLUDE_CDS 583 int ClassLoader::get_shared_paths_misc_info_size() { 584 return _shared_paths_misc_info->get_used_bytes(); 585 } 586 587 void* ClassLoader::get_shared_paths_misc_info() { 588 return _shared_paths_misc_info->buffer(); 589 } 590 591 bool ClassLoader::check_shared_paths_misc_info(void *buf, int size, bool is_static) { 592 SharedPathsMiscInfo* checker = new SharedPathsMiscInfo((char*)buf, size); 593 bool result = checker->check(is_static); 594 delete checker; 595 return result; 596 } 597 598 void ClassLoader::setup_app_search_path(const char *class_path) { 599 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity"); 600 601 ResourceMark rm; 602 ClasspathStream cp_stream(class_path); 603 604 while (cp_stream.has_next()) { 605 const char* path = cp_stream.get_next(); 606 update_class_path_entry_list(path, false, false, false); 607 } 608 } 609 610 void ClassLoader::add_to_module_path_entries(const char* path, 611 ClassPathEntry* entry) { 612 assert(entry != NULL, "ClassPathEntry should not be NULL"); 613 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only"); 614 615 // The entry does not exist, add to the list 616 if (_module_path_entries == NULL) { 617 assert(_last_module_path_entry == NULL, "Sanity"); 618 _module_path_entries = _last_module_path_entry = entry; 619 } else { 620 _last_module_path_entry->set_next(entry); 621 _last_module_path_entry = entry; 622 } 623 } 624 625 // Add a module path to the _module_path_entries list. 626 void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) { 646 void ClassLoader::setup_module_search_path(const char* path, TRAPS) { 647 update_module_path_entry_list(path, THREAD); 648 } 649 650 #endif // INCLUDE_CDS 651 652 void ClassLoader::close_jrt_image() { 653 // Not applicable for exploded builds 654 if (!ClassLoader::has_jrt_entry()) return; 655 _jrt_entry->close_jimage(); 656 } 657 658 // Construct the array of module/path pairs as specified to --patch-module 659 // for the boot loader to search ahead of the jimage, if the class being 660 // loaded is defined to a module that has been specified to --patch-module. 661 void ClassLoader::setup_patch_mod_entries() { 662 Thread* THREAD = Thread::current(); 663 GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix(); 664 int num_of_entries = patch_mod_args->length(); 665 666 // Set up the boot loader's _patch_mod_entries list 667 _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true); 668 669 for (int i = 0; i < num_of_entries; i++) { 670 const char* module_name = (patch_mod_args->at(i))->module_name(); 671 Symbol* const module_sym = SymbolTable::new_symbol(module_name); 672 assert(module_sym != NULL, "Failed to obtain Symbol for module name"); 673 ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym); 674 675 char* class_path = (patch_mod_args->at(i))->path_string(); 676 ResourceMark rm(THREAD); 677 ClasspathStream cp_stream(class_path); 678 679 while (cp_stream.has_next()) { 680 const char* path = cp_stream.get_next(); 681 struct stat st; 682 if (os::stat(path, &st) == 0) { 683 // File or directory found 684 ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK); 685 // If the path specification is valid, enter it into this module's list 686 if (new_entry != NULL) { 687 module_cpl->add_to_list(new_entry); 688 } 689 } 690 } 691 692 // Record the module into the list of --patch-module entries only if 693 // valid ClassPathEntrys have been created 694 if (module_cpl->module_first_entry() != NULL) { 695 _patch_mod_entries->push(module_cpl); 696 } 697 } 698 } 699 700 // Determine whether the module has been patched via the command-line 701 // option --patch-module 702 bool ClassLoader::is_in_patch_mod_entries(Symbol* module_name) { 703 if (_patch_mod_entries != NULL && _patch_mod_entries->is_nonempty()) { 704 int table_len = _patch_mod_entries->length(); 705 for (int i = 0; i < table_len; i++) { 706 ModuleClassPathList* patch_mod = _patch_mod_entries->at(i); 707 if (module_name->fast_compare(patch_mod->module_name()) == 0) { 708 return true; 709 } 710 } 711 } 712 return false; 713 } 714 715 // Set up the _jrt_entry if present and boot append path 716 void ClassLoader::setup_boot_search_path(const char *class_path) { 717 EXCEPTION_MARK; 718 ResourceMark rm(THREAD); 719 ClasspathStream cp_stream(class_path); 720 bool set_base_piece = true; 721 722 #if INCLUDE_CDS 723 if (DumpSharedSpaces || DynamicDumpSharedSpaces) { 724 if (!Arguments::has_jimage()) { 725 vm_exit_during_initialization("CDS is not supported in exploded JDK build", NULL); 726 } 727 } 728 #endif 729 730 while (cp_stream.has_next()) { 731 const char* path = cp_stream.get_next(); 732 733 if (set_base_piece) { 734 // The first time through the bootstrap_search setup, it must be determined 735 // what the base or core piece of the boot loader search is. Either a java runtime 736 // image is present or this is an exploded module build situation. 737 assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, JAVA_BASE_NAME), 738 "Incorrect boot loader search path, no java runtime image or " JAVA_BASE_NAME " exploded build"); 739 struct stat st; 740 if (os::stat(path, &st) == 0) { 741 // Directory found 742 ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK); 743 744 // Check for a jimage 745 if (Arguments::has_jimage()) { 746 assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice"); 747 _jrt_entry = new_entry; 748 assert(new_entry != NULL && new_entry->is_modules_image(), "No java runtime image present"); 749 assert(_jrt_entry->jimage() != NULL, "No java runtime image"); 750 } 751 } else { 752 // If path does not exist, exit 753 vm_exit_during_initialization("Unable to establish the boot loader search path", path); 754 } 755 set_base_piece = false; 756 } else { 757 // Every entry on the system boot class path after the initial base piece, 758 // which is set by os::set_boot_path(), is considered an appended entry. 759 update_class_path_entry_list(path, false, true, false); 760 } 761 } 762 } 763 764 // During an exploded modules build, each module defined to the boot loader 765 // will be added to the ClassLoader::_exploded_entries array. 766 void ClassLoader::add_to_exploded_build_list(Symbol* module_sym, TRAPS) { 767 assert(!ClassLoader::has_jrt_entry(), "Exploded build not applicable"); 768 assert(_exploded_entries != NULL, "_exploded_entries was not initialized"); 769 770 // Find the module's symbol 771 ResourceMark rm(THREAD); 772 const char *module_name = module_sym->as_C_string(); 773 const char *home = Arguments::get_java_home(); 774 const char file_sep = os::file_separator()[0]; 775 // 10 represents the length of "modules" + 2 file separators + \0 776 size_t len = strlen(home) + strlen(module_name) + 10; 777 char *path = NEW_RESOURCE_ARRAY(char, len); 778 jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name); 779 |