274 if (ze == NULL) break; |
270 if (ze == NULL) break; |
275 (*f)(ze->name, context); |
271 (*f)(ze->name, context); |
276 } |
272 } |
277 } |
273 } |
278 |
274 |
279 LazyClassPathEntry::LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception) : ClassPathEntry() { |
|
280 _path = os::strdup_check_oom(path); |
|
281 _st = *st; |
|
282 _resolved_entry = NULL; |
|
283 _has_error = false; |
|
284 _throw_exception = throw_exception; |
|
285 } |
|
286 |
|
287 LazyClassPathEntry::~LazyClassPathEntry() { |
|
288 os::free((void*)_path); |
|
289 } |
|
290 |
|
291 bool LazyClassPathEntry::is_jar_file() { |
|
292 size_t len = strlen(_path); |
|
293 if (len < 4 || strcmp(_path + len - 4, ".jar") != 0) return false; |
|
294 return ((_st.st_mode & S_IFREG) == S_IFREG); |
|
295 } |
|
296 |
|
297 ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) { |
|
298 if (_resolved_entry != NULL) { |
|
299 return (ClassPathEntry*) _resolved_entry; |
|
300 } |
|
301 ClassPathEntry* new_entry = NULL; |
|
302 new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, _throw_exception, CHECK_NULL); |
|
303 if (!_throw_exception && new_entry == NULL) { |
|
304 assert(!HAS_PENDING_EXCEPTION, "must be"); |
|
305 return NULL; |
|
306 } |
|
307 { |
|
308 ThreadCritical tc; |
|
309 if (_resolved_entry == NULL) { |
|
310 _resolved_entry = new_entry; |
|
311 return new_entry; |
|
312 } |
|
313 } |
|
314 assert(_resolved_entry != NULL, "bug in MT-safe resolution logic"); |
|
315 delete new_entry; |
|
316 return (ClassPathEntry*) _resolved_entry; |
|
317 } |
|
318 |
|
319 ClassFileStream* LazyClassPathEntry::open_stream(const char* name, TRAPS) { |
|
320 if (_has_error) { |
|
321 return NULL; |
|
322 } |
|
323 ClassPathEntry* cpe = resolve_entry(THREAD); |
|
324 if (cpe == NULL) { |
|
325 _has_error = true; |
|
326 return NULL; |
|
327 } else { |
|
328 return cpe->open_stream(name, THREAD); |
|
329 } |
|
330 } |
|
331 |
|
332 bool LazyClassPathEntry::is_lazy() { |
|
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) : |
275 ClassPathImageEntry::ClassPathImageEntry(ImageFileReader* image) : |
354 ClassPathEntry(), |
276 ClassPathEntry(), |
355 _image(image), |
277 _image(image), |
356 _module_data(NULL) { |
278 _module_data(NULL) { |
357 guarantee(image != NULL, "image file is null"); |
279 guarantee(image != NULL, "image file is null"); |
562 } |
484 } |
563 } |
485 } |
564 } |
486 } |
565 |
487 |
566 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st, |
488 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st, |
567 bool lazy, bool throw_exception, TRAPS) { |
489 bool throw_exception, TRAPS) { |
568 JavaThread* thread = JavaThread::current(); |
490 JavaThread* thread = JavaThread::current(); |
569 if (lazy) { |
|
570 return new LazyClassPathEntry(path, st, throw_exception); |
|
571 } |
|
572 ClassPathEntry* new_entry = NULL; |
491 ClassPathEntry* new_entry = NULL; |
573 if ((st->st_mode & S_IFREG) == S_IFREG) { |
492 if ((st->st_mode & S_IFREG) == S_IFREG) { |
574 // Regular file, should be a zip or image file |
493 // Regular file, should be a zip or image file |
575 // Canonicalized filename |
494 // Canonicalized filename |
576 char canonical_path[JVM_MAXPATHLEN]; |
495 char canonical_path[JVM_MAXPATHLEN]; |
584 } |
503 } |
585 ImageFileReader* image = ImageFileReader::open(canonical_path); |
504 ImageFileReader* image = ImageFileReader::open(canonical_path); |
586 if (image != NULL) { |
505 if (image != NULL) { |
587 new_entry = new ClassPathImageEntry(image); |
506 new_entry = new ClassPathImageEntry(image); |
588 } else { |
507 } else { |
589 char* error_msg = NULL; |
508 char* error_msg = NULL; |
590 jzfile* zip; |
509 jzfile* zip; |
591 { |
510 { |
592 // enable call to C land |
511 // enable call to C land |
593 ThreadToNativeFromVM ttn(thread); |
512 ThreadToNativeFromVM ttn(thread); |
594 HandleMark hm(thread); |
513 HandleMark hm(thread); |
595 zip = (*ZipOpen)(canonical_path, &error_msg); |
514 zip = (*ZipOpen)(canonical_path, &error_msg); |
596 } |
515 } |
597 if (zip != NULL && error_msg == NULL) { |
516 if (zip != NULL && error_msg == NULL) { |
598 new_entry = new ClassPathZipEntry(zip, path); |
517 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 { |
518 } else { |
606 int len = (int)(strlen(path) + strlen(error_msg) + 128); |
519 ResourceMark rm(thread); |
607 msg = NEW_RESOURCE_ARRAY(char, len); ; |
520 char *msg; |
608 jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path); |
521 if (error_msg == NULL) { |
609 } |
522 msg = NEW_RESOURCE_ARRAY(char, strlen(path) + 128); ; |
610 if (throw_exception) { |
523 jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path); |
611 THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL); |
524 } else { |
612 } else { |
525 int len = (int)(strlen(path) + strlen(error_msg) + 128); |
613 return NULL; |
526 msg = NEW_RESOURCE_ARRAY(char, len); ; |
614 } |
527 jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path); |
615 } |
528 } |
|
529 // Don't complain about bad jar files added via -Xbootclasspath/a:. |
|
530 if (throw_exception && is_init_completed()) { |
|
531 THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL); |
|
532 } else { |
|
533 return NULL; |
|
534 } |
|
535 } |
616 } |
536 } |
617 if (TraceClassLoading || TraceClassPaths) { |
537 if (TraceClassLoading || TraceClassPaths) { |
618 tty->print_cr("[Opened %s]", path); |
538 tty->print_cr("[Opened %s]", path); |
619 } |
539 } |
620 } else { |
540 } else { |
688 struct stat st; |
608 struct stat st; |
689 if (os::stat(path, &st) == 0) { |
609 if (os::stat(path, &st) == 0) { |
690 // File or directory found |
610 // File or directory found |
691 ClassPathEntry* new_entry = NULL; |
611 ClassPathEntry* new_entry = NULL; |
692 Thread* THREAD = Thread::current(); |
612 Thread* THREAD = Thread::current(); |
693 new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, throw_exception, CHECK_(false)); |
613 new_entry = create_class_path_entry(path, &st, throw_exception, CHECK_(false)); |
694 if (new_entry == NULL) { |
614 if (new_entry == NULL) { |
695 return false; |
615 return false; |
696 } |
616 } |
697 // The kernel VM adds dynamically to the end of the classloader path and |
617 // The kernel VM adds dynamically to the end of the classloader path and |
698 // doesn't reorder the bootclasspath which would break java.lang.Package |
618 // doesn't reorder the bootclasspath which would break java.lang.Package |
1339 } |
1259 } |
1340 } |
1260 } |
1341 |
1261 |
1342 bool ClassPathZipEntry::is_jrt() { |
1262 bool ClassPathZipEntry::is_jrt() { |
1343 return false; |
1263 return false; |
1344 } |
|
1345 |
|
1346 void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) { |
|
1347 ClassPathEntry* cpe = resolve_entry(THREAD); |
|
1348 if (cpe != NULL) { |
|
1349 cpe->compile_the_world(loader, CHECK); |
|
1350 } |
|
1351 } |
|
1352 |
|
1353 bool LazyClassPathEntry::is_jrt() { |
|
1354 Thread* THREAD = Thread::current(); |
|
1355 ClassPathEntry* cpe = resolve_entry(THREAD); |
|
1356 return (cpe != NULL) ? cpe->is_jar_file() : false; |
|
1357 } |
1264 } |
1358 |
1265 |
1359 void ClassLoader::compile_the_world() { |
1266 void ClassLoader::compile_the_world() { |
1360 EXCEPTION_MARK; |
1267 EXCEPTION_MARK; |
1361 HandleMark hm(THREAD); |
1268 HandleMark hm(THREAD); |