253 return pkgEntryTable->lookup_only(pkg_symbol);
254 }
255
256 ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
257 char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
258 strcpy(copy, dir);
259 _dir = copy;
260 }
261
262
263 ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
264 // construct full path name
265 assert((_dir != NULL) && (name != NULL), "sanity");
266 size_t path_len = strlen(_dir) + strlen(name) + strlen(os::file_separator()) + 1;
267 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len);
268 int len = jio_snprintf(path, path_len, "%s%s%s", _dir, os::file_separator(), name);
269 assert(len == (int)(path_len - 1), "sanity");
270 // check if file exists
271 struct stat st;
272 if (os::stat(path, &st) == 0) {
273 #if INCLUDE_CDS
274 if (DumpSharedSpaces) {
275 // We have already check in ClassLoader::check_shared_classpath() that the directory is empty, so
276 // we should never find a file underneath it -- unless user has added a new file while we are running
277 // the dump, in which case let's quit!
278 ShouldNotReachHere();
279 }
280 #endif
281 // found file, open it
282 int file_handle = os::open(path, 0, 0);
283 if (file_handle != -1) {
284 // read contents into resource array
285 u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size);
286 size_t num_read = os::read(file_handle, (char*) buffer, st.st_size);
287 // close file
288 os::close(file_handle);
289 // construct ClassFileStream
290 if (num_read == (size_t)st.st_size) {
291 if (UsePerfData) {
292 ClassLoader::perf_sys_classfile_bytes_read()->inc(num_read);
293 }
294 FREE_RESOURCE_ARRAY(char, path, path_len);
295 // Resource allocated
296 return new ClassFileStream(buffer,
297 st.st_size,
298 _dir,
299 ClassFileStream::verify);
300 }
696
697 void ClassLoader::setup_app_search_path(const char *class_path) {
698
699 assert(DumpSharedSpaces, "Sanity");
700
701 Thread* THREAD = Thread::current();
702 int len = (int)strlen(class_path);
703 int end = 0;
704
705 // Iterate over class path entries
706 for (int start = 0; start < len; start = end) {
707 while (class_path[end] && class_path[end] != os::path_separator()[0]) {
708 end++;
709 }
710 EXCEPTION_MARK;
711 ResourceMark rm(THREAD);
712 char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
713 strncpy(path, &class_path[start], end - start);
714 path[end - start] = '\0';
715
716 check_shared_classpath(path);
717
718 update_class_path_entry_list(path, false, false);
719
720 while (class_path[end] == os::path_separator()[0]) {
721 end++;
722 }
723 }
724 }
725
726 void ClassLoader::add_to_module_path_entries(const char* path,
727 ClassPathEntry* entry) {
728 assert(entry != NULL, "ClassPathEntry should not be NULL");
729 assert(DumpSharedSpaces, "dump time only");
730
731 // The entry does not exist, add to the list
732 if (_module_path_entries == NULL) {
733 assert(_last_module_path_entry == NULL, "Sanity");
734 _module_path_entries = _last_module_path_entry = entry;
735 } else {
736 _last_module_path_entry->set_next(entry);
737 _last_module_path_entry = entry;
740
741 // Add a module path to the _module_path_entries list.
742 void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
743 assert(DumpSharedSpaces, "dump time only");
744 struct stat st;
745 int ret = os::stat(path, &st);
746 assert(ret == 0, "module path must exist");
747 // File or directory found
748 ClassPathEntry* new_entry = NULL;
749 new_entry = create_class_path_entry(path, &st, true /* throw_exception */,
750 false /*is_boot_append */, CHECK);
751 if (new_entry == NULL) {
752 return;
753 }
754
755 add_to_module_path_entries(path, new_entry);
756 return;
757 }
758
759 void ClassLoader::setup_module_search_path(const char* path, TRAPS) {
760 check_shared_classpath(path);
761 update_module_path_entry_list(path, THREAD);
762 }
763 #endif // INCLUDE_CDS
764
765 // Construct the array of module/path pairs as specified to --patch-module
766 // for the boot loader to search ahead of the jimage, if the class being
767 // loaded is defined to a module that has been specified to --patch-module.
768 void ClassLoader::setup_patch_mod_entries() {
769 Thread* THREAD = Thread::current();
770 GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
771 int num_of_entries = patch_mod_args->length();
772
773
774 // Set up the boot loader's _patch_mod_entries list
775 _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
776
777 for (int i = 0; i < num_of_entries; i++) {
778 const char* module_name = (patch_mod_args->at(i))->module_name();
779 Symbol* const module_sym = SymbolTable::lookup(module_name, (int)strlen(module_name), CHECK);
780 assert(module_sym != NULL, "Failed to obtain Symbol for module name");
869 ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
870
871 // Check for a jimage
872 if (Arguments::has_jimage()) {
873 assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice");
874 assert(new_entry != NULL && new_entry->is_modules_image(), "No java runtime image present");
875 _jrt_entry = new_entry;
876 assert(_jrt_entry->jimage() != NULL, "No java runtime image");
877 }
878 } else {
879 // If path does not exist, exit
880 vm_exit_during_initialization("Unable to establish the boot loader search path", path);
881 }
882 set_base_piece = false;
883 } else {
884 // Every entry on the system boot class path after the initial base piece,
885 // which is set by os::set_boot_path(), is considered an appended entry.
886 update_class_path_entry_list(path, false, true);
887 }
888
889 #if INCLUDE_CDS
890 if (DumpSharedSpaces) {
891 check_shared_classpath(path);
892 }
893 #endif
894 while (class_path[end] == os::path_separator()[0]) {
895 end++;
896 }
897 }
898 }
899
900 // During an exploded modules build, each module defined to the boot loader
901 // will be added to the ClassLoader::_exploded_entries array.
902 void ClassLoader::add_to_exploded_build_list(Symbol* module_sym, TRAPS) {
903 assert(!ClassLoader::has_jrt_entry(), "Exploded build not applicable");
904 assert(_exploded_entries != NULL, "_exploded_entries was not initialized");
905
906 // Find the module's symbol
907 ResourceMark rm(THREAD);
908 const char *module_name = module_sym->as_C_string();
909 const char *home = Arguments::get_java_home();
910 const char file_sep = os::file_separator()[0];
911 // 10 represents the length of "modules" + 2 file separators + \0
912 size_t len = strlen(home) + strlen(module_name) + 10;
913 char *path = NEW_RESOURCE_ARRAY(char, len);
1065 while (e != NULL) {
1066 if (strcmp(e->name(), entry->name()) == 0) {
1067 // entry already exists
1068 return;
1069 }
1070 e = e->next();
1071 }
1072 }
1073
1074 // The entry does not exist, add to the list
1075 if (_app_classpath_entries == NULL) {
1076 assert(_last_app_classpath_entry == NULL, "Sanity");
1077 _app_classpath_entries = _last_app_classpath_entry = entry;
1078 } else {
1079 _last_app_classpath_entry->set_next(entry);
1080 _last_app_classpath_entry = entry;
1081 }
1082
1083 if (entry->is_jar_file()) {
1084 ClassLoaderExt::process_jar_manifest(entry, check_for_duplicates);
1085 } else {
1086 if (!os::dir_is_empty(path)) {
1087 tty->print_cr("Error: non-empty directory '%s'", path);
1088 exit_with_path_failure("Cannot have non-empty directory in app classpaths", NULL);
1089 }
1090 }
1091 #endif
1092 }
1093
1094 // Returns true IFF the file/dir exists and the entry was successfully created.
1095 bool ClassLoader::update_class_path_entry_list(const char *path,
1096 bool check_for_duplicates,
1097 bool is_boot_append,
1098 bool throw_exception) {
1099 struct stat st;
1100 if (os::stat(path, &st) == 0) {
1101 // File or directory found
1102 ClassPathEntry* new_entry = NULL;
1103 Thread* THREAD = Thread::current();
1104 new_entry = create_class_path_entry(path, &st, throw_exception, is_boot_append, CHECK_(false));
1105 if (new_entry == NULL) {
1106 return false;
1107 }
1108
1109 // Do not reorder the bootclasspath which would break get_system_package().
|
253 return pkgEntryTable->lookup_only(pkg_symbol);
254 }
255
256 ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
257 char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
258 strcpy(copy, dir);
259 _dir = copy;
260 }
261
262
263 ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
264 // construct full path name
265 assert((_dir != NULL) && (name != NULL), "sanity");
266 size_t path_len = strlen(_dir) + strlen(name) + strlen(os::file_separator()) + 1;
267 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len);
268 int len = jio_snprintf(path, path_len, "%s%s%s", _dir, os::file_separator(), name);
269 assert(len == (int)(path_len - 1), "sanity");
270 // check if file exists
271 struct stat st;
272 if (os::stat(path, &st) == 0) {
273 // found file, open it
274 int file_handle = os::open(path, 0, 0);
275 if (file_handle != -1) {
276 // read contents into resource array
277 u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size);
278 size_t num_read = os::read(file_handle, (char*) buffer, st.st_size);
279 // close file
280 os::close(file_handle);
281 // construct ClassFileStream
282 if (num_read == (size_t)st.st_size) {
283 if (UsePerfData) {
284 ClassLoader::perf_sys_classfile_bytes_read()->inc(num_read);
285 }
286 FREE_RESOURCE_ARRAY(char, path, path_len);
287 // Resource allocated
288 return new ClassFileStream(buffer,
289 st.st_size,
290 _dir,
291 ClassFileStream::verify);
292 }
688
689 void ClassLoader::setup_app_search_path(const char *class_path) {
690
691 assert(DumpSharedSpaces, "Sanity");
692
693 Thread* THREAD = Thread::current();
694 int len = (int)strlen(class_path);
695 int end = 0;
696
697 // Iterate over class path entries
698 for (int start = 0; start < len; start = end) {
699 while (class_path[end] && class_path[end] != os::path_separator()[0]) {
700 end++;
701 }
702 EXCEPTION_MARK;
703 ResourceMark rm(THREAD);
704 char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
705 strncpy(path, &class_path[start], end - start);
706 path[end - start] = '\0';
707
708 update_class_path_entry_list(path, false, false);
709
710 while (class_path[end] == os::path_separator()[0]) {
711 end++;
712 }
713 }
714 }
715
716 void ClassLoader::add_to_module_path_entries(const char* path,
717 ClassPathEntry* entry) {
718 assert(entry != NULL, "ClassPathEntry should not be NULL");
719 assert(DumpSharedSpaces, "dump time only");
720
721 // The entry does not exist, add to the list
722 if (_module_path_entries == NULL) {
723 assert(_last_module_path_entry == NULL, "Sanity");
724 _module_path_entries = _last_module_path_entry = entry;
725 } else {
726 _last_module_path_entry->set_next(entry);
727 _last_module_path_entry = entry;
730
731 // Add a module path to the _module_path_entries list.
732 void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
733 assert(DumpSharedSpaces, "dump time only");
734 struct stat st;
735 int ret = os::stat(path, &st);
736 assert(ret == 0, "module path must exist");
737 // File or directory found
738 ClassPathEntry* new_entry = NULL;
739 new_entry = create_class_path_entry(path, &st, true /* throw_exception */,
740 false /*is_boot_append */, CHECK);
741 if (new_entry == NULL) {
742 return;
743 }
744
745 add_to_module_path_entries(path, new_entry);
746 return;
747 }
748
749 void ClassLoader::setup_module_search_path(const char* path, TRAPS) {
750 update_module_path_entry_list(path, THREAD);
751 }
752 #endif // INCLUDE_CDS
753
754 // Construct the array of module/path pairs as specified to --patch-module
755 // for the boot loader to search ahead of the jimage, if the class being
756 // loaded is defined to a module that has been specified to --patch-module.
757 void ClassLoader::setup_patch_mod_entries() {
758 Thread* THREAD = Thread::current();
759 GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
760 int num_of_entries = patch_mod_args->length();
761
762
763 // Set up the boot loader's _patch_mod_entries list
764 _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
765
766 for (int i = 0; i < num_of_entries; i++) {
767 const char* module_name = (patch_mod_args->at(i))->module_name();
768 Symbol* const module_sym = SymbolTable::lookup(module_name, (int)strlen(module_name), CHECK);
769 assert(module_sym != NULL, "Failed to obtain Symbol for module name");
858 ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
859
860 // Check for a jimage
861 if (Arguments::has_jimage()) {
862 assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice");
863 assert(new_entry != NULL && new_entry->is_modules_image(), "No java runtime image present");
864 _jrt_entry = new_entry;
865 assert(_jrt_entry->jimage() != NULL, "No java runtime image");
866 }
867 } else {
868 // If path does not exist, exit
869 vm_exit_during_initialization("Unable to establish the boot loader search path", path);
870 }
871 set_base_piece = false;
872 } else {
873 // Every entry on the system boot class path after the initial base piece,
874 // which is set by os::set_boot_path(), is considered an appended entry.
875 update_class_path_entry_list(path, false, true);
876 }
877
878 while (class_path[end] == os::path_separator()[0]) {
879 end++;
880 }
881 }
882 }
883
884 // During an exploded modules build, each module defined to the boot loader
885 // will be added to the ClassLoader::_exploded_entries array.
886 void ClassLoader::add_to_exploded_build_list(Symbol* module_sym, TRAPS) {
887 assert(!ClassLoader::has_jrt_entry(), "Exploded build not applicable");
888 assert(_exploded_entries != NULL, "_exploded_entries was not initialized");
889
890 // Find the module's symbol
891 ResourceMark rm(THREAD);
892 const char *module_name = module_sym->as_C_string();
893 const char *home = Arguments::get_java_home();
894 const char file_sep = os::file_separator()[0];
895 // 10 represents the length of "modules" + 2 file separators + \0
896 size_t len = strlen(home) + strlen(module_name) + 10;
897 char *path = NEW_RESOURCE_ARRAY(char, len);
1049 while (e != NULL) {
1050 if (strcmp(e->name(), entry->name()) == 0) {
1051 // entry already exists
1052 return;
1053 }
1054 e = e->next();
1055 }
1056 }
1057
1058 // The entry does not exist, add to the list
1059 if (_app_classpath_entries == NULL) {
1060 assert(_last_app_classpath_entry == NULL, "Sanity");
1061 _app_classpath_entries = _last_app_classpath_entry = entry;
1062 } else {
1063 _last_app_classpath_entry->set_next(entry);
1064 _last_app_classpath_entry = entry;
1065 }
1066
1067 if (entry->is_jar_file()) {
1068 ClassLoaderExt::process_jar_manifest(entry, check_for_duplicates);
1069 }
1070 #endif
1071 }
1072
1073 // Returns true IFF the file/dir exists and the entry was successfully created.
1074 bool ClassLoader::update_class_path_entry_list(const char *path,
1075 bool check_for_duplicates,
1076 bool is_boot_append,
1077 bool throw_exception) {
1078 struct stat st;
1079 if (os::stat(path, &st) == 0) {
1080 // File or directory found
1081 ClassPathEntry* new_entry = NULL;
1082 Thread* THREAD = Thread::current();
1083 new_entry = create_class_path_entry(path, &st, throw_exception, is_boot_append, CHECK_(false));
1084 if (new_entry == NULL) {
1085 return false;
1086 }
1087
1088 // Do not reorder the bootclasspath which would break get_system_package().
|