245 PackageEntry* ClassLoader::get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) { 246 ResourceMark rm(THREAD); 247 const char *pkg_name = ClassLoader::package_from_name(class_name); 248 if (pkg_name == NULL) { 249 return NULL; 250 } 251 PackageEntryTable* pkgEntryTable = loader_data->packages(); 252 TempNewSymbol pkg_symbol = SymbolTable::new_symbol(pkg_name, CHECK_NULL); 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 char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, JVM_MAXPATHLEN); 266 if (jio_snprintf(path, JVM_MAXPATHLEN, "%s%s%s", _dir, os::file_separator(), name) == -1) { 267 FREE_RESOURCE_ARRAY(char, path, JVM_MAXPATHLEN); 268 return NULL; 269 } 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, JVM_MAXPATHLEN); 295 // Resource allocated 296 return new ClassFileStream(buffer, 297 st.st_size, 298 _dir, 299 ClassFileStream::verify); 300 } 301 } 302 } 303 FREE_RESOURCE_ARRAY(char, path, JVM_MAXPATHLEN); 304 return NULL; 305 } 306 307 ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append) : ClassPathEntry() { 308 _zip = zip; 309 char *copy = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass); 310 strcpy(copy, zip_name); 311 _zip_name = copy; 312 _is_boot_append = is_boot_append; 313 _multi_versioned = _unknown; 314 } 315 316 ClassPathZipEntry::~ClassPathZipEntry() { 317 if (ZipClose != NULL) { 318 (*ZipClose)(_zip); 319 } 320 FREE_C_HEAP_ARRAY(char, _zip_name); 321 } 322 323 u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) { 364 int version = 0; 365 const int base_version = 8; // JDK8 366 int cur_ver = JDK_Version::current().major_version(); 367 if (verstr != NULL) { 368 version = atoi(verstr); 369 if (version < base_version || version > cur_ver) { 370 // If the specified version is lower than the base version, the base 371 // entry will be used; if the version is higher than the current 372 // jdk version, the highest versioned entry will be used. 373 if (version < base_version) { 374 is_multi_ver = false; 375 } 376 // print out warning, do not use assertion here since it will continue to look 377 // for proper version. 378 warning("JDK%d is not supported in multiple version jars", version); 379 } 380 } 381 382 if (is_multi_ver) { 383 int n; 384 char* entry_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, JVM_MAXPATHLEN); 385 if (version > 0) { 386 n = jio_snprintf(entry_name, JVM_MAXPATHLEN, "META-INF/versions/%d/%s", version, name); 387 entry_name[n] = '\0'; 388 buffer = open_entry((const char*)entry_name, filesize, false, CHECK_NULL); 389 if (buffer == NULL) { 390 warning("Could not find %s in %s, try to find highest version instead", entry_name, _zip_name); 391 } 392 } 393 if (buffer == NULL) { 394 for (int i = cur_ver; i >= base_version; i--) { 395 n = jio_snprintf(entry_name, JVM_MAXPATHLEN, "META-INF/versions/%d/%s", i, name); 396 entry_name[n] = '\0'; 397 buffer = open_entry((const char*)entry_name, filesize, false, CHECK_NULL); 398 if (buffer != NULL) { 399 break; 400 } 401 } 402 } 403 FREE_RESOURCE_ARRAY(char, entry_name, JVM_MAXPATHLEN); 404 } 405 } 406 return buffer; 407 } 408 409 bool ClassPathZipEntry::is_multiple_versioned(TRAPS) { 410 assert(DumpSharedSpaces, "called only at dump time"); 411 if (_multi_versioned != _unknown) { 412 return (_multi_versioned == _yes) ? true : false; 413 } 414 jint size; 415 char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, true, CHECK_false); 416 if (buffer != NULL) { 417 char* p = buffer; 418 for ( ; *p; ++p) *p = tolower(*p); 419 if (strstr(buffer, "multi-release: true") != NULL) { 420 _multi_versioned = _yes; 421 return true; 422 } 423 } | 245 PackageEntry* ClassLoader::get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) { 246 ResourceMark rm(THREAD); 247 const char *pkg_name = ClassLoader::package_from_name(class_name); 248 if (pkg_name == NULL) { 249 return NULL; 250 } 251 PackageEntryTable* pkgEntryTable = loader_data->packages(); 252 TempNewSymbol pkg_symbol = SymbolTable::new_symbol(pkg_name, CHECK_NULL); 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 } 301 } 302 } 303 FREE_RESOURCE_ARRAY(char, path, path_len); 304 return NULL; 305 } 306 307 ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append) : ClassPathEntry() { 308 _zip = zip; 309 char *copy = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass); 310 strcpy(copy, zip_name); 311 _zip_name = copy; 312 _is_boot_append = is_boot_append; 313 _multi_versioned = _unknown; 314 } 315 316 ClassPathZipEntry::~ClassPathZipEntry() { 317 if (ZipClose != NULL) { 318 (*ZipClose)(_zip); 319 } 320 FREE_C_HEAP_ARRAY(char, _zip_name); 321 } 322 323 u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) { 364 int version = 0; 365 const int base_version = 8; // JDK8 366 int cur_ver = JDK_Version::current().major_version(); 367 if (verstr != NULL) { 368 version = atoi(verstr); 369 if (version < base_version || version > cur_ver) { 370 // If the specified version is lower than the base version, the base 371 // entry will be used; if the version is higher than the current 372 // jdk version, the highest versioned entry will be used. 373 if (version < base_version) { 374 is_multi_ver = false; 375 } 376 // print out warning, do not use assertion here since it will continue to look 377 // for proper version. 378 warning("JDK%d is not supported in multiple version jars", version); 379 } 380 } 381 382 if (is_multi_ver) { 383 int n; 384 const char* version_entry = "META-INF/versions/"; 385 // 10 is the max length of a decimal 32-bit non-negative number 386 // 2 includes the '/' and trailing zero 387 size_t entry_name_len = strlen(version_entry) + 10 + strlen(name) + 2; 388 char* entry_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, entry_name_len); 389 if (version > 0) { 390 n = jio_snprintf(entry_name, entry_name_len, "%s%d/%s", version_entry, version, name); 391 entry_name[n] = '\0'; 392 buffer = open_entry((const char*)entry_name, filesize, false, CHECK_NULL); 393 if (buffer == NULL) { 394 warning("Could not find %s in %s, try to find highest version instead", entry_name, _zip_name); 395 } 396 } 397 if (buffer == NULL) { 398 for (int i = cur_ver; i >= base_version; i--) { 399 n = jio_snprintf(entry_name, entry_name_len, "%s%d/%s", version_entry, i, name); 400 entry_name[n] = '\0'; 401 buffer = open_entry((const char*)entry_name, filesize, false, CHECK_NULL); 402 if (buffer != NULL) { 403 break; 404 } 405 } 406 } 407 FREE_RESOURCE_ARRAY(char, entry_name, entry_name_len); 408 } 409 } 410 return buffer; 411 } 412 413 bool ClassPathZipEntry::is_multiple_versioned(TRAPS) { 414 assert(DumpSharedSpaces, "called only at dump time"); 415 if (_multi_versioned != _unknown) { 416 return (_multi_versioned == _yes) ? true : false; 417 } 418 jint size; 419 char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, true, CHECK_false); 420 if (buffer != NULL) { 421 char* p = buffer; 422 for ( ; *p; ++p) *p = tolower(*p); 423 if (strstr(buffer, "multi-release: true") != NULL) { 424 _multi_versioned = _yes; 425 return true; 426 } 427 } |