< prev index next >

src/share/vm/classfile/classLoader.cpp

Print this page




  51 #include "runtime/fprofiler.hpp"
  52 #include "runtime/handles.hpp"
  53 #include "runtime/handles.inline.hpp"
  54 #include "runtime/init.hpp"
  55 #include "runtime/interfaceSupport.hpp"
  56 #include "runtime/java.hpp"
  57 #include "runtime/javaCalls.hpp"
  58 #include "runtime/os.hpp"
  59 #include "runtime/threadCritical.hpp"
  60 #include "runtime/timer.hpp"
  61 #include "services/management.hpp"
  62 #include "services/threadService.hpp"
  63 #include "utilities/events.hpp"
  64 #include "utilities/hashtable.inline.hpp"
  65 #include "utilities/macros.hpp"
  66 #if INCLUDE_CDS
  67 #include "classfile/sharedClassUtil.hpp"
  68 #include "classfile/sharedPathsMiscInfo.hpp"
  69 #endif
  70 
  71 
  72 // Entry points in zip.dll for loading zip/jar file entries and image file entries
  73 
  74 typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg);
  75 typedef void (JNICALL *ZipClose_t)(jzfile *zip);
  76 typedef jzentry* (JNICALL *FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen);
  77 typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
  78 typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
  79 typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
  80 typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
  81 typedef jint     (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
  82 
  83 static ZipOpen_t         ZipOpen            = NULL;
  84 static ZipClose_t        ZipClose           = NULL;
  85 static FindEntry_t       FindEntry          = NULL;
  86 static ReadEntry_t       ReadEntry          = NULL;
  87 static ReadMappedEntry_t ReadMappedEntry    = NULL;
  88 static GetNextEntry_t    GetNextEntry       = NULL;
  89 static canonicalize_fn_t CanonicalizeEntry  = NULL;
  90 static ZipInflateFully_t ZipInflateFully    = NULL;
  91 static Crc32_t           Crc32              = NULL;


 150   }
 151   return (strncmp(str + (str_len - str_to_find_len), str_to_find, str_to_find_len) == 0);
 152 }
 153 
 154 
 155 ClassPathEntry::ClassPathEntry() {
 156   set_next(NULL);
 157 }
 158 
 159 
 160 bool ClassPathEntry::is_lazy() {
 161   return false;
 162 }
 163 
 164 ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
 165   char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
 166   strcpy(copy, dir);
 167   _dir = copy;
 168 }
 169 
 170 
 171 ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
 172   // construct full path name
 173   char path[JVM_MAXPATHLEN];
 174   if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) {
 175     return NULL;
 176   }
 177   // check if file exists
 178   struct stat st;
 179   if (os::stat(path, &st) == 0) {
 180 #if INCLUDE_CDS
 181     if (DumpSharedSpaces) {
 182       // We have already check in ClassLoader::check_shared_classpath() that the directory is empty, so
 183       // we should never find a file underneath it -- unless user has added a new file while we are running
 184       // the dump, in which case let's quit!
 185       ShouldNotReachHere();
 186     }
 187 #endif
 188     // found file, open it
 189     int file_handle = os::open(path, 0, 0);
 190     if (file_handle != -1) {


 335   return true;
 336 }
 337 
 338 u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
 339   if (_has_error) {
 340     return NULL;
 341   }
 342   ClassPathEntry* cpe = resolve_entry(THREAD);
 343   if (cpe == NULL) {
 344     _has_error = true;
 345     return NULL;
 346   } else if (cpe->is_jar_file()) {
 347     return ((ClassPathZipEntry*)cpe)->open_entry(name, filesize, nul_terminate,THREAD);
 348   } else {
 349     ShouldNotReachHere();
 350     *filesize = 0;
 351     return NULL;
 352   }
 353 }
 354 
 355 ClassPathImageEntry::ClassPathImageEntry(char* name) : ClassPathEntry(), _image(new ImageFile(name)) {
 356   bool opened = _image->open();
 357   if (!opened) {
 358     _image = NULL;
 359   }




 360 }
 361 
 362 ClassPathImageEntry::~ClassPathImageEntry() {
 363   if (_image) {
 364     _image->close();





 365     _image = NULL;
 366   }
 367 }
 368 
 369 const char* ClassPathImageEntry::name() {
 370   return _image ? _image->name() : "";
 371 }
 372 
 373 ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
 374   u1* buffer;
 375   u8 size;
 376   _image->get_resource(name, buffer, size);



 377 
 378   if (buffer) {



















 379     if (UsePerfData) {
 380       ClassLoader::perf_sys_classfile_bytes_read()->inc(size);
 381     }
 382     return new ClassFileStream(buffer, (int)size, (char*)name);  // Resource allocated


 383   }
 384 
 385   return NULL;
 386 }
 387 
 388 #ifndef PRODUCT
 389 void ClassPathImageEntry::compile_the_world(Handle loader, TRAPS) {
 390   tty->print_cr("CompileTheWorld : Compiling all classes in %s", name());
 391   tty->cr();
 392   const ImageStrings strings = _image->get_strings();
 393   // Retrieve each path component string.
 394   u4 count = _image->get_location_count();
 395   for (u4 i = 0; i < count; i++) {
 396     u1* location_data = _image->get_location_data(i);
 397 
 398     if (location_data) {
 399        ImageLocation location(location_data);
 400        const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
 401        const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
 402        const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
 403        assert((strlen(parent) + strlen(base) + strlen(extension)) < JVM_MAXPATHLEN, "path exceeds buffer");
 404        char path[JVM_MAXPATHLEN];
 405        strcpy(path, parent);
 406        strcat(path, base);
 407        strcat(path, extension);
 408        ClassLoader::compile_the_world_in(path, loader, CHECK);
 409     }
 410   }
 411   if (HAS_PENDING_EXCEPTION) {
 412   if (PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) {
 413     CLEAR_PENDING_EXCEPTION;
 414     tty->print_cr("\nCompileTheWorld : Ran out of memory\n");
 415     tty->print_cr("Increase class metadata storage if a limit was set");
 416   } else {
 417     tty->print_cr("\nCompileTheWorld : Unexpected exception occurred\n");
 418   }
 419   }
 420 }
 421 
 422 bool ClassPathImageEntry::is_jrt() {
 423   return string_ends_with(name(), "bootmodules.jimage");
 424 }
 425 #endif
 426 
 427 #if INCLUDE_CDS
 428 void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
 429   assert(DumpSharedSpaces, "only called at dump time");
 430   tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure");
 431   vm_exit_during_initialization(error, message);
 432 }
 433 #endif
 434 
 435 void ClassLoader::trace_class_path(const char* msg, const char* name) {
 436   if (!TraceClassPaths) {
 437     return;
 438   }
 439 
 440   if (msg) {
 441     tty->print("%s", msg);
 442   }
 443   if (name) {


 540 
 541 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
 542                                                      bool lazy, bool throw_exception, TRAPS) {
 543   JavaThread* thread = JavaThread::current();
 544   if (lazy) {
 545     return new LazyClassPathEntry(path, st, throw_exception);
 546   }
 547   ClassPathEntry* new_entry = NULL;
 548   if ((st->st_mode & S_IFREG) == S_IFREG) {
 549     // Regular file, should be a zip or image file
 550     // Canonicalized filename
 551     char canonical_path[JVM_MAXPATHLEN];
 552     if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
 553       // This matches the classic VM
 554       if (throw_exception) {
 555         THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
 556       } else {
 557         return NULL;
 558       }
 559     }
 560     // TODO - add proper criteria for selecting image file
 561     ClassPathImageEntry* entry = new ClassPathImageEntry(canonical_path);
 562     if (entry->is_open()) {
 563       new_entry = entry;
 564     } else {
 565     char* error_msg = NULL;
 566     jzfile* zip;
 567     {
 568       // enable call to C land
 569       ThreadToNativeFromVM ttn(thread);
 570       HandleMark hm(thread);
 571       zip = (*ZipOpen)(canonical_path, &error_msg);
 572     }
 573     if (zip != NULL && error_msg == NULL) {
 574       new_entry = new ClassPathZipEntry(zip, path);
 575     } else {
 576       ResourceMark rm(thread);
 577       char *msg;
 578       if (error_msg == NULL) {
 579         msg = NEW_RESOURCE_ARRAY(char, strlen(path) + 128); ;
 580         jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
 581       } else {
 582         int len = (int)(strlen(path) + strlen(error_msg) + 128);
 583         msg = NEW_RESOURCE_ARRAY(char, len); ;




  51 #include "runtime/fprofiler.hpp"
  52 #include "runtime/handles.hpp"
  53 #include "runtime/handles.inline.hpp"
  54 #include "runtime/init.hpp"
  55 #include "runtime/interfaceSupport.hpp"
  56 #include "runtime/java.hpp"
  57 #include "runtime/javaCalls.hpp"
  58 #include "runtime/os.hpp"
  59 #include "runtime/threadCritical.hpp"
  60 #include "runtime/timer.hpp"
  61 #include "services/management.hpp"
  62 #include "services/threadService.hpp"
  63 #include "utilities/events.hpp"
  64 #include "utilities/hashtable.inline.hpp"
  65 #include "utilities/macros.hpp"
  66 #if INCLUDE_CDS
  67 #include "classfile/sharedClassUtil.hpp"
  68 #include "classfile/sharedPathsMiscInfo.hpp"
  69 #endif
  70 

  71 // Entry points in zip.dll for loading zip/jar file entries and image file entries
  72 
  73 typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg);
  74 typedef void (JNICALL *ZipClose_t)(jzfile *zip);
  75 typedef jzentry* (JNICALL *FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen);
  76 typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
  77 typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
  78 typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
  79 typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
  80 typedef jint     (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
  81 
  82 static ZipOpen_t         ZipOpen            = NULL;
  83 static ZipClose_t        ZipClose           = NULL;
  84 static FindEntry_t       FindEntry          = NULL;
  85 static ReadEntry_t       ReadEntry          = NULL;
  86 static ReadMappedEntry_t ReadMappedEntry    = NULL;
  87 static GetNextEntry_t    GetNextEntry       = NULL;
  88 static canonicalize_fn_t CanonicalizeEntry  = NULL;
  89 static ZipInflateFully_t ZipInflateFully    = NULL;
  90 static Crc32_t           Crc32              = NULL;


 149   }
 150   return (strncmp(str + (str_len - str_to_find_len), str_to_find, str_to_find_len) == 0);
 151 }
 152 
 153 
 154 ClassPathEntry::ClassPathEntry() {
 155   set_next(NULL);
 156 }
 157 
 158 
 159 bool ClassPathEntry::is_lazy() {
 160   return false;
 161 }
 162 
 163 ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
 164   char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
 165   strcpy(copy, dir);
 166   _dir = copy;
 167 }
 168 

 169 ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
 170   // construct full path name
 171   char path[JVM_MAXPATHLEN];
 172   if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) {
 173     return NULL;
 174   }
 175   // check if file exists
 176   struct stat st;
 177   if (os::stat(path, &st) == 0) {
 178 #if INCLUDE_CDS
 179     if (DumpSharedSpaces) {
 180       // We have already check in ClassLoader::check_shared_classpath() that the directory is empty, so
 181       // we should never find a file underneath it -- unless user has added a new file while we are running
 182       // the dump, in which case let's quit!
 183       ShouldNotReachHere();
 184     }
 185 #endif
 186     // found file, open it
 187     int file_handle = os::open(path, 0, 0);
 188     if (file_handle != -1) {


 333   return true;
 334 }
 335 
 336 u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
 337   if (_has_error) {
 338     return NULL;
 339   }
 340   ClassPathEntry* cpe = resolve_entry(THREAD);
 341   if (cpe == NULL) {
 342     _has_error = true;
 343     return NULL;
 344   } else if (cpe->is_jar_file()) {
 345     return ((ClassPathZipEntry*)cpe)->open_entry(name, filesize, nul_terminate,THREAD);
 346   } else {
 347     ShouldNotReachHere();
 348     *filesize = 0;
 349     return NULL;
 350   }
 351 }
 352 
 353 ClassPathImageEntry::ClassPathImageEntry(ImageFileReader* image) :
 354   ClassPathEntry(),
 355   _image(image),
 356   _module_data(NULL) {
 357   guarantee(image != NULL, "image file is null");
 358 
 359   char module_data_name[JVM_MAXPATHLEN];
 360   ImageModuleData::module_data_name(module_data_name, _image->name());
 361   _module_data = new ImageModuleData(_image, module_data_name);
 362 }
 363 
 364 ClassPathImageEntry::~ClassPathImageEntry() {
 365   if (_module_data != NULL) {
 366     delete _module_data;
 367     _module_data = NULL;
 368   }
 369 
 370   if (_image != NULL) {
 371     ImageFileReader::close(_image);
 372     _image = NULL;
 373   }
 374 }
 375 
 376 const char* ClassPathImageEntry::name() {
 377   return _image ? _image->name() : "";
 378 }
 379 
 380 ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
 381   ImageLocation location;
 382   bool found = _image->find_location(name, location);
 383 
 384   if (!found) {
 385     const char *pslash = strrchr(name, '/');
 386     int len = pslash - name;
 387 
 388     // NOTE: IMAGE_MAX_PATH is used here since this path is internal to the jimage
 389     // (effectively unlimited.)  There are several JCK tests that use paths over
 390     // 1024 characters long, the limit on Windows systems.
 391     if (pslash && 0 < len && len < IMAGE_MAX_PATH) {
 392 
 393       char path[IMAGE_MAX_PATH];
 394       strncpy(path, name, len);
 395       path[len] = '\0';
 396       const char* moduleName = _module_data->package_to_module(path);
 397 
 398       if (moduleName != NULL && (len + strlen(moduleName) + 2) < IMAGE_MAX_PATH) {
 399         jio_snprintf(path, IMAGE_MAX_PATH - 1, "/%s/%s", moduleName, name);
 400         location.clear_data();
 401         found = _image->find_location(path, location);
 402       }
 403     }
 404   }
 405 
 406   if (found) {
 407     u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
 408     if (UsePerfData) {
 409       ClassLoader::perf_sys_classfile_bytes_read()->inc(size);
 410     }
 411     u1* data = NEW_RESOURCE_ARRAY(u1, size);
 412     _image->get_resource(location, data);
 413     return new ClassFileStream(data, (int)size, _image->name());  // Resource allocated
 414   }
 415 
 416   return NULL;
 417 }
 418 
 419 #ifndef PRODUCT
 420 void ClassPathImageEntry::compile_the_world(Handle loader, TRAPS) {
 421   tty->print_cr("CompileTheWorld : Compiling all classes in %s", name());
 422   tty->cr();
 423   const ImageStrings strings = _image->get_strings();
 424   // Retrieve each path component string.
 425   u4 length = _image->table_length();
 426   for (u4 i = 0; i < length; i++) {
 427     u1* location_data = _image->get_location_data(i);
 428 
 429     if (location_data != NULL) {
 430        ImageLocation location(location_data);
 431        char path[IMAGE_MAX_PATH];
 432        _image->location_path(location, path, IMAGE_MAX_PATH);






 433        ClassLoader::compile_the_world_in(path, loader, CHECK);
 434     }
 435   }
 436   if (HAS_PENDING_EXCEPTION) {
 437   if (PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) {
 438     CLEAR_PENDING_EXCEPTION;
 439     tty->print_cr("\nCompileTheWorld : Ran out of memory\n");
 440     tty->print_cr("Increase class metadata storage if a limit was set");
 441   } else {
 442     tty->print_cr("\nCompileTheWorld : Unexpected exception occurred\n");
 443   }
 444   }
 445 }
 446 
 447 bool ClassPathImageEntry::is_jrt() {
 448   return string_ends_with(name(), BOOT_IMAGE_NAME);
 449 }
 450 #endif
 451 
 452 #if INCLUDE_CDS
 453 void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
 454   assert(DumpSharedSpaces, "only called at dump time");
 455   tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure");
 456   vm_exit_during_initialization(error, message);
 457 }
 458 #endif
 459 
 460 void ClassLoader::trace_class_path(const char* msg, const char* name) {
 461   if (!TraceClassPaths) {
 462     return;
 463   }
 464 
 465   if (msg) {
 466     tty->print("%s", msg);
 467   }
 468   if (name) {


 565 
 566 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
 567                                                      bool lazy, bool throw_exception, TRAPS) {
 568   JavaThread* thread = JavaThread::current();
 569   if (lazy) {
 570     return new LazyClassPathEntry(path, st, throw_exception);
 571   }
 572   ClassPathEntry* new_entry = NULL;
 573   if ((st->st_mode & S_IFREG) == S_IFREG) {
 574     // Regular file, should be a zip or image file
 575     // Canonicalized filename
 576     char canonical_path[JVM_MAXPATHLEN];
 577     if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
 578       // This matches the classic VM
 579       if (throw_exception) {
 580         THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
 581       } else {
 582         return NULL;
 583       }
 584     }
 585     ImageFileReader* image = ImageFileReader::open(canonical_path);
 586     if (image != NULL) {
 587       new_entry = new ClassPathImageEntry(image);

 588     } else {
 589     char* error_msg = NULL;
 590     jzfile* zip;
 591     {
 592       // enable call to C land
 593       ThreadToNativeFromVM ttn(thread);
 594       HandleMark hm(thread);
 595       zip = (*ZipOpen)(canonical_path, &error_msg);
 596     }
 597     if (zip != NULL && error_msg == NULL) {
 598       new_entry = new ClassPathZipEntry(zip, path);
 599     } else {
 600       ResourceMark rm(thread);
 601       char *msg;
 602       if (error_msg == NULL) {
 603         msg = NEW_RESOURCE_ARRAY(char, strlen(path) + 128); ;
 604         jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
 605       } else {
 606         int len = (int)(strlen(path) + strlen(error_msg) + 128);
 607         msg = NEW_RESOURCE_ARRAY(char, len); ;


< prev index next >