< prev index next >

src/hotspot/share/classfile/classLoader.cpp

Print this page

 681     } else {
 682       // Every entry on the boot class path after the initial base piece,
 683       // which is set by os::set_boot_path(), is considered an appended entry.
 684       update_class_path_entry_list(current, path);
 685     }
 686   }
 687 }
 688 
 689 // Gets the exploded path for the named module. The memory for the path
 690 // is allocated on the C heap if `c_heap` is true otherwise in the resource area.
 691 static const char* get_exploded_module_path(const char* module_name, bool c_heap) {
 692   const char *home = Arguments::get_java_home();
 693   const char file_sep = os::file_separator()[0];
 694   // 10 represents the length of "modules" (7) + 2 file separators + \0
 695   size_t len = strlen(home) + strlen(module_name) + 10;
 696   char *path = c_heap ? NEW_C_HEAP_ARRAY(char, len, mtModule) : NEW_RESOURCE_ARRAY(char, len);
 697   jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
 698   return path;
 699 }
 700 










 701 // During an exploded modules build, each module defined to the boot loader
 702 // will be added to the ClassLoader::_exploded_entries array.
 703 void ClassLoader::add_to_exploded_build_list(JavaThread* current, Symbol* module_sym) {
 704   assert(!ClassLoader::has_jrt_entry(), "Exploded build not applicable");
 705   assert(_exploded_entries != nullptr, "_exploded_entries was not initialized");
 706 
 707   // Find the module's symbol
 708   ResourceMark rm(current);
 709   const char *module_name = module_sym->as_C_string();
 710   const char *path = get_exploded_module_path(module_name, false);
 711 
 712   struct stat st;
 713   if (os::stat(path, &st) == 0) {
 714     // Directory found
 715     ClassPathEntry* new_entry = create_class_path_entry(current, path, &st);
 716 
 717     // If the path specification is valid, enter it into this module's list.
 718     // There is no need to check for duplicate modules in the exploded entry list,
 719     // since no two modules with the same name can be defined to the boot loader.
 720     // This is checked at module definition time in Modules::define_module.
 721     if (new_entry != nullptr) {
 722       ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);















 723       module_cpl->add_to_list(new_entry);
 724       {
 725         MutexLocker ml(current, Module_lock);
 726         _exploded_entries->push(module_cpl);
 727       }
 728       log_info(class, load)("path: %s", path);
 729     }
 730   }
 731 }
 732 
 733 jzfile* ClassLoader::open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread) {
 734   // enable call to C land
 735   ThreadToNativeFromVM ttn(thread);
 736   HandleMark hm(thread);
 737   return ZipLibrary::open(canonical_path, error_msg);
 738 }
 739 
 740 ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current,
 741                                                      const char *path, const struct stat* st) {
 742   ClassPathEntry* new_entry = nullptr;
 743   if ((st->st_mode & S_IFMT) == S_IFREG) {
 744     ResourceMark rm(current);
 745     // Regular file, should be a zip file
 746     // Canonicalized filename
 747     const char* canonical_path = get_canonical_path(path, current);
 748     if (canonical_path == nullptr) {

 947 
 948     // Return null if package does not exist or if no classes in that package
 949     // have been loaded.
 950     if (package != nullptr && package->has_loaded_class()) {
 951       ModuleEntry* module = package->module();
 952       if (module->location() != nullptr) {
 953         ResourceMark rm(THREAD);
 954         Handle ml = java_lang_String::create_from_str(
 955           module->location()->as_C_string(), THREAD);
 956         return ml();
 957       }
 958       // Return entry on boot loader class path.
 959       Handle cph = java_lang_String::create_from_str(
 960         ClassLoader::classpath_entry(package->classpath_index())->name(), THREAD);
 961       return cph();
 962     }
 963   }
 964   return nullptr;
 965 }
 966 
 967 objArrayOop ClassLoader::get_system_packages(TRAPS) {
 968   ResourceMark rm(THREAD);
 969   // List of pointers to PackageEntrys that have loaded classes.
 970   PackageEntryTable* pe_table =
 971       ClassLoaderData::the_null_class_loader_data()->packages();
 972   GrowableArray<PackageEntry*>* loaded_class_pkgs = pe_table->get_system_packages();
 973 
 974   // Allocate objArray and fill with java.lang.String
 975   objArrayOop r = oopFactory::new_objArray(vmClasses::String_klass(),
 976                                            loaded_class_pkgs->length(), CHECK_NULL);
 977   objArrayHandle result(THREAD, r);

 978   for (int x = 0; x < loaded_class_pkgs->length(); x++) {
 979     PackageEntry* package_entry = loaded_class_pkgs->at(x);
 980     Handle str = java_lang_String::create_from_symbol(package_entry->name(), CHECK_NULL);
 981     result->obj_at_put(x, str());
 982   }
 983   return result();
 984 }
 985 
 986 // caller needs ResourceMark
 987 const char* ClassLoader::file_name_for_class_name(const char* class_name,
 988                                                   int class_name_len) {
 989   assert(class_name != nullptr, "invariant");
 990   assert((int)strlen(class_name) == class_name_len, "invariant");
 991 
 992   static const char class_suffix[] = ".class";
 993   size_t class_suffix_len = sizeof(class_suffix);
 994 
 995   char* const file_name = NEW_RESOURCE_ARRAY(char,
 996                                              class_name_len +
 997                                              class_suffix_len); // includes term null

1074 
1075 // Called by the boot classloader to load classes
1076 InstanceKlass* ClassLoader::load_class(Symbol* name, PackageEntry* pkg_entry, bool search_append_only, TRAPS) {
1077   assert(name != nullptr, "invariant");
1078 
1079   ResourceMark rm(THREAD);
1080   HandleMark hm(THREAD);
1081 
1082   const char* const class_name = name->as_C_string();
1083 
1084   EventMarkClassLoading m("Loading class %s", class_name);
1085 
1086   const char* const file_name = file_name_for_class_name(class_name,
1087                                                          name->utf8_length());
1088   assert(file_name != nullptr, "invariant");
1089 
1090   // Lookup stream for parsing .class file
1091   ClassFileStream* stream = nullptr;
1092   s2 classpath_index = 0;
1093   ClassPathEntry* e = nullptr;

1094 
1095   // If search_append_only is true, boot loader visibility boundaries are
1096   // set to be _first_append_entry to the end. This includes:
1097   //   [-Xbootclasspath/a]; [jvmti appended entries]
1098   //
1099   // If search_append_only is false, boot loader visibility boundaries are
1100   // set to be the --patch-module entries plus the base piece. This includes:
1101   //   [--patch-module=<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build]
1102   //
1103 
1104   // Load Attempt #1: --patch-module
1105   // Determine the class' defining module.  If it appears in the _patch_mod_entries,
1106   // attempt to load the class from those locations specific to the module.
1107   // Specifications to --patch-module can contain a partial number of classes
1108   // that are part of the overall module definition.  So if a particular class is not
1109   // found within its module specification, the search should continue to Load Attempt #2.
1110   // Note: The --patch-module entries are never searched if the boot loader's
1111   //       visibility boundary is limited to only searching the append entries.
1112   if (_patch_mod_entries != nullptr && !search_append_only) {
1113     assert(!CDSConfig::is_dumping_archive(), "CDS doesn't support --patch-module during dumping");
1114     stream = search_module_entries(THREAD, _patch_mod_entries, pkg_entry, file_name);














1115   }
1116 
1117   // Load Attempt #2: [jimage | exploded build]
1118   if (!search_append_only && (nullptr == stream)) {
1119     if (has_jrt_entry()) {
1120       e = _jrt_entry;
1121       stream = _jrt_entry->open_stream(THREAD, file_name);
1122     } else {
1123       // Exploded build - attempt to locate class in its defining module's location.
1124       assert(_exploded_entries != nullptr, "No exploded build entries present");
1125       assert(!CDSConfig::is_dumping_archive(), "CDS dumping doesn't support exploded build");
1126       stream = search_module_entries(THREAD, _exploded_entries, pkg_entry, file_name);
1127     }
1128   }
1129 
1130   // Load Attempt #3: [-Xbootclasspath/a]; [jvmti appended entries]
1131   if (search_append_only && (nullptr == stream)) {
1132     // For the boot loader append path search, the starting classpath_index
1133     // for the appended piece is always 1 to account for either the
1134     // _jrt_entry or the _exploded_entries.

1143       }
1144       e = e->next();
1145       ++classpath_index;
1146     }
1147   }
1148 
1149   if (nullptr == stream) {
1150     return nullptr;
1151   }
1152 
1153   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
1154   Handle protection_domain;
1155   ClassLoadInfo cl_info(protection_domain);
1156 
1157   InstanceKlass* result = KlassFactory::create_from_stream(stream,
1158                                                            name,
1159                                                            loader_data,
1160                                                            cl_info,
1161                                                            CHECK_NULL);
1162   result->set_classpath_index(classpath_index);



1163   return result;
1164 }
1165 
1166 #if INCLUDE_CDS
1167 static const char* skip_uri_protocol(const char* source) {
1168   if (strncmp(source, "file:", 5) == 0) {
1169     // file: protocol path could start with file:/ or file:///
1170     // locate the char after all the forward slashes
1171     int offset = 5;
1172     while (*(source + offset) == '/') {
1173         offset++;
1174     }
1175     source += offset;
1176   // for non-windows platforms, move back one char as the path begins with a '/'
1177 #ifndef _WINDOWS
1178     source -= 1;
1179 #endif
1180   } else if (strncmp(source, "jrt:/", 5) == 0) {
1181     source += 5;
1182   }

1219   for (size_t i = 0; i < strlen(uri); ++i) {
1220     char decoded = decode_percent_encoded(uri, i);
1221     path[path_index++] = decoded;
1222   }
1223   path[path_index] = '\0';
1224   return path;
1225 }
1226 
1227 // Record the shared classpath index and loader type for classes loaded
1228 // by the builtin loaders at dump time.
1229 void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik,
1230                                 const ClassFileStream* stream, bool redefined) {
1231   assert(CDSConfig::is_dumping_archive(), "sanity");
1232   assert(stream != nullptr, "sanity");
1233 
1234   if (ik->is_hidden()) {
1235     record_hidden_class(ik);
1236     return;
1237   }
1238 




1239   oop loader = ik->class_loader();
1240   char* src = (char*)stream->source();
1241   if (src == nullptr) {
1242     ik->set_shared_classpath_index(-1); // unsupported location
1243     return;
1244   }
1245 
1246   if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
1247     // A class loaded by a user-defined classloader.
1248     assert(ik->shared_classpath_index() < 0, "not assigned yet");
1249     ik->set_shared_classpath_index(UNREGISTERED_INDEX);
1250     SystemDictionaryShared::set_shared_class_misc_info(ik, (ClassFileStream*)stream);
1251     return;
1252   }
1253 
1254   assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build");
1255 
1256   ResourceMark rm(current);
1257   int classpath_index = -1;
1258   bool found_invalid = false;

 681     } else {
 682       // Every entry on the boot class path after the initial base piece,
 683       // which is set by os::set_boot_path(), is considered an appended entry.
 684       update_class_path_entry_list(current, path);
 685     }
 686   }
 687 }
 688 
 689 // Gets the exploded path for the named module. The memory for the path
 690 // is allocated on the C heap if `c_heap` is true otherwise in the resource area.
 691 static const char* get_exploded_module_path(const char* module_name, bool c_heap) {
 692   const char *home = Arguments::get_java_home();
 693   const char file_sep = os::file_separator()[0];
 694   // 10 represents the length of "modules" (7) + 2 file separators + \0
 695   size_t len = strlen(home) + strlen(module_name) + 10;
 696   char *path = c_heap ? NEW_C_HEAP_ARRAY(char, len, mtModule) : NEW_RESOURCE_ARRAY(char, len);
 697   jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
 698   return path;
 699 }
 700 
 701 // Gets a preview path for a given class path as a resource.
 702 static const char* get_preview_path(const char* path) {
 703   const char file_sep = os::file_separator()[0];
 704   // 18 represents the length of "META-INF" (8) + "preview" (7) + 2 file separators + \0
 705   size_t len = strlen(path) + 18;
 706   char *preview_path = NEW_RESOURCE_ARRAY(char, len);
 707   jio_snprintf(preview_path, len, "%s%cMETA-INF%cpreview", path, file_sep, file_sep);
 708   return preview_path;
 709 }
 710 
 711 // During an exploded modules build, each module defined to the boot loader
 712 // will be added to the ClassLoader::_exploded_entries array.
 713 void ClassLoader::add_to_exploded_build_list(JavaThread* current, Symbol* module_sym) {
 714   assert(!ClassLoader::has_jrt_entry(), "Exploded build not applicable");
 715   assert(_exploded_entries != nullptr, "_exploded_entries was not initialized");
 716 
 717   // Find the module's symbol
 718   ResourceMark rm(current);
 719   const char *module_name = module_sym->as_C_string();
 720   const char *path = get_exploded_module_path(module_name, false);
 721 
 722   struct stat st;
 723   if (os::stat(path, &st) == 0) {
 724     // Directory found
 725     ClassPathEntry* new_entry = create_class_path_entry(current, path, &st);

 726     // If the path specification is valid, enter it into this module's list.
 727     // There is no need to check for duplicate modules in the exploded entry list,
 728     // since no two modules with the same name can be defined to the boot loader.
 729     // This is checked at module definition time in Modules::define_module.
 730     if (new_entry != nullptr) {
 731       ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
 732       log_info(class, load)("path: %s", path);
 733 
 734       // If we are in preview mode, attempt to add a preview entry *before* the
 735       // new class path entry if a preview path exists.
 736       if (is_preview_enabled()) {
 737         const char* preview_path = get_preview_path(path);
 738         if (os::stat(preview_path, &st) == 0) {
 739           ClassPathEntry* preview_entry = create_class_path_entry(current, preview_path, &st);
 740           if (preview_entry != nullptr) {
 741             module_cpl->add_to_list(preview_entry);
 742             log_info(class, load)("preview path: %s", preview_path);
 743           }
 744         }
 745       }
 746 
 747       module_cpl->add_to_list(new_entry);
 748       {
 749         MutexLocker ml(current, Module_lock);
 750         _exploded_entries->push(module_cpl);
 751       }

 752     }
 753   }
 754 }
 755 
 756 jzfile* ClassLoader::open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread) {
 757   // enable call to C land
 758   ThreadToNativeFromVM ttn(thread);
 759   HandleMark hm(thread);
 760   return ZipLibrary::open(canonical_path, error_msg);
 761 }
 762 
 763 ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current,
 764                                                      const char *path, const struct stat* st) {
 765   ClassPathEntry* new_entry = nullptr;
 766   if ((st->st_mode & S_IFMT) == S_IFREG) {
 767     ResourceMark rm(current);
 768     // Regular file, should be a zip file
 769     // Canonicalized filename
 770     const char* canonical_path = get_canonical_path(path, current);
 771     if (canonical_path == nullptr) {

 970 
 971     // Return null if package does not exist or if no classes in that package
 972     // have been loaded.
 973     if (package != nullptr && package->has_loaded_class()) {
 974       ModuleEntry* module = package->module();
 975       if (module->location() != nullptr) {
 976         ResourceMark rm(THREAD);
 977         Handle ml = java_lang_String::create_from_str(
 978           module->location()->as_C_string(), THREAD);
 979         return ml();
 980       }
 981       // Return entry on boot loader class path.
 982       Handle cph = java_lang_String::create_from_str(
 983         ClassLoader::classpath_entry(package->classpath_index())->name(), THREAD);
 984       return cph();
 985     }
 986   }
 987   return nullptr;
 988 }
 989 
 990 refArrayOop ClassLoader::get_system_packages(TRAPS) {
 991   ResourceMark rm(THREAD);
 992   // List of pointers to PackageEntrys that have loaded classes.
 993   PackageEntryTable* pe_table =
 994       ClassLoaderData::the_null_class_loader_data()->packages();
 995   GrowableArray<PackageEntry*>* loaded_class_pkgs = pe_table->get_system_packages();
 996 
 997   // Allocate objArray and fill with java.lang.String
 998   refArrayOop r = oopFactory::new_refArray(vmClasses::String_klass(),
 999                                            loaded_class_pkgs->length(),
1000                                            CHECK_NULL);
1001   refArrayHandle result(THREAD, r);
1002   for (int x = 0; x < loaded_class_pkgs->length(); x++) {
1003     PackageEntry* package_entry = loaded_class_pkgs->at(x);
1004     Handle str = java_lang_String::create_from_symbol(package_entry->name(), CHECK_NULL);
1005     result->obj_at_put(x, str());
1006   }
1007   return result();
1008 }
1009 
1010 // caller needs ResourceMark
1011 const char* ClassLoader::file_name_for_class_name(const char* class_name,
1012                                                   int class_name_len) {
1013   assert(class_name != nullptr, "invariant");
1014   assert((int)strlen(class_name) == class_name_len, "invariant");
1015 
1016   static const char class_suffix[] = ".class";
1017   size_t class_suffix_len = sizeof(class_suffix);
1018 
1019   char* const file_name = NEW_RESOURCE_ARRAY(char,
1020                                              class_name_len +
1021                                              class_suffix_len); // includes term null

1098 
1099 // Called by the boot classloader to load classes
1100 InstanceKlass* ClassLoader::load_class(Symbol* name, PackageEntry* pkg_entry, bool search_append_only, TRAPS) {
1101   assert(name != nullptr, "invariant");
1102 
1103   ResourceMark rm(THREAD);
1104   HandleMark hm(THREAD);
1105 
1106   const char* const class_name = name->as_C_string();
1107 
1108   EventMarkClassLoading m("Loading class %s", class_name);
1109 
1110   const char* const file_name = file_name_for_class_name(class_name,
1111                                                          name->utf8_length());
1112   assert(file_name != nullptr, "invariant");
1113 
1114   // Lookup stream for parsing .class file
1115   ClassFileStream* stream = nullptr;
1116   s2 classpath_index = 0;
1117   ClassPathEntry* e = nullptr;
1118   bool is_patched = false;
1119 
1120   // If search_append_only is true, boot loader visibility boundaries are
1121   // set to be _first_append_entry to the end. This includes:
1122   //   [-Xbootclasspath/a]; [jvmti appended entries]
1123   //
1124   // If search_append_only is false, boot loader visibility boundaries are
1125   // set to be the --patch-module entries plus the base piece. This includes:
1126   //   [--patch-module=<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build]
1127   //
1128 
1129   // Load Attempt #1: --patch-module
1130   // Determine the class' defining module.  If it appears in the _patch_mod_entries,
1131   // attempt to load the class from those locations specific to the module.
1132   // Specifications to --patch-module can contain a partial number of classes
1133   // that are part of the overall module definition.  So if a particular class is not
1134   // found within its module specification, the search should continue to Load Attempt #2.
1135   // Note: The --patch-module entries are never searched if the boot loader's
1136   //       visibility boundary is limited to only searching the append entries.
1137   if (_patch_mod_entries != nullptr && !search_append_only) {
1138     // At CDS dump time, the --patch-module entries are ignored. That means a
1139     // class is still loaded from the runtime image even if it might
1140     // appear in the _patch_mod_entries. The runtime shared class visibility
1141     // check will determine if a shared class is visible based on the runtime
1142     // environment, including the runtime --patch-module setting.
1143     if (!Arguments::is_valhalla_enabled()) {
1144       // Dynamic dumping requires UseSharedSpaces to be enabled. Since --patch-module
1145       // is not supported with UseSharedSpaces, we can never come here during dynamic dumping.
1146       assert(!CDSConfig::is_dumping_archive(), "CDS doesn't support --patch-module during dumping");
1147     }
1148     if (Arguments::is_valhalla_enabled() || !CDSConfig::is_dumping_static_archive()) {
1149       stream = search_module_entries(THREAD, _patch_mod_entries, pkg_entry, file_name);
1150       if (stream != nullptr) {
1151         is_patched = true;
1152       }
1153     }
1154   }
1155 
1156   // Load Attempt #2: [jimage | exploded build]
1157   if (!search_append_only && (nullptr == stream)) {
1158     if (has_jrt_entry()) {
1159       e = _jrt_entry;
1160       stream = _jrt_entry->open_stream(THREAD, file_name);
1161     } else {
1162       // Exploded build - attempt to locate class in its defining module's location.
1163       assert(_exploded_entries != nullptr, "No exploded build entries present");
1164       assert(!CDSConfig::is_dumping_archive(), "CDS dumping doesn't support exploded build");
1165       stream = search_module_entries(THREAD, _exploded_entries, pkg_entry, file_name);
1166     }
1167   }
1168 
1169   // Load Attempt #3: [-Xbootclasspath/a]; [jvmti appended entries]
1170   if (search_append_only && (nullptr == stream)) {
1171     // For the boot loader append path search, the starting classpath_index
1172     // for the appended piece is always 1 to account for either the
1173     // _jrt_entry or the _exploded_entries.

1182       }
1183       e = e->next();
1184       ++classpath_index;
1185     }
1186   }
1187 
1188   if (nullptr == stream) {
1189     return nullptr;
1190   }
1191 
1192   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
1193   Handle protection_domain;
1194   ClassLoadInfo cl_info(protection_domain);
1195 
1196   InstanceKlass* result = KlassFactory::create_from_stream(stream,
1197                                                            name,
1198                                                            loader_data,
1199                                                            cl_info,
1200                                                            CHECK_NULL);
1201   result->set_classpath_index(classpath_index);
1202   if (is_patched) {
1203     result->set_shared_classpath_index(0);
1204   }
1205   return result;
1206 }
1207 
1208 #if INCLUDE_CDS
1209 static const char* skip_uri_protocol(const char* source) {
1210   if (strncmp(source, "file:", 5) == 0) {
1211     // file: protocol path could start with file:/ or file:///
1212     // locate the char after all the forward slashes
1213     int offset = 5;
1214     while (*(source + offset) == '/') {
1215         offset++;
1216     }
1217     source += offset;
1218   // for non-windows platforms, move back one char as the path begins with a '/'
1219 #ifndef _WINDOWS
1220     source -= 1;
1221 #endif
1222   } else if (strncmp(source, "jrt:/", 5) == 0) {
1223     source += 5;
1224   }

1261   for (size_t i = 0; i < strlen(uri); ++i) {
1262     char decoded = decode_percent_encoded(uri, i);
1263     path[path_index++] = decoded;
1264   }
1265   path[path_index] = '\0';
1266   return path;
1267 }
1268 
1269 // Record the shared classpath index and loader type for classes loaded
1270 // by the builtin loaders at dump time.
1271 void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik,
1272                                 const ClassFileStream* stream, bool redefined) {
1273   assert(CDSConfig::is_dumping_archive(), "sanity");
1274   assert(stream != nullptr, "sanity");
1275 
1276   if (ik->is_hidden()) {
1277     record_hidden_class(ik);
1278     return;
1279   }
1280 
1281   if (ik->shared_classpath_index() == 0 && ik->defined_by_boot_loader()) {
1282     return;
1283   }
1284 
1285   oop loader = ik->class_loader();
1286   char* src = (char*)stream->source();
1287   if (src == nullptr) {
1288     ik->set_shared_classpath_index(-1); // unsupported location
1289     return;
1290   }
1291 
1292   if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
1293     // A class loaded by a user-defined classloader.
1294     assert(ik->shared_classpath_index() < 0, "not assigned yet");
1295     ik->set_shared_classpath_index(UNREGISTERED_INDEX);
1296     SystemDictionaryShared::set_shared_class_misc_info(ik, (ClassFileStream*)stream);
1297     return;
1298   }
1299 
1300   assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build");
1301 
1302   ResourceMark rm(current);
1303   int classpath_index = -1;
1304   bool found_invalid = false;
< prev index next >