< prev index next >

src/hotspot/share/classfile/classLoader.cpp

Print this page


 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 


< prev index next >