comparison src/share/vm/prims/jvm.cpp @ 878:abe076e3636f

6864003: Modify JVM_FindClassFromBootLoader to return null if class not found Summary: JVM_FindClassFromBootLoader returns null if class not found Reviewed-by: acorn, alanb, dholmes
author mchung
date Mon, 27 Jul 2009 09:06:22 -0700
parents 6a93908f268f
children ad6585fd4087
comparison
equal deleted inserted replaced
877:8c79517a9300 878:abe076e3636f
636 JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls)) 636 JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls))
637 JVMWrapper("JVM_ResolveClass"); 637 JVMWrapper("JVM_ResolveClass");
638 if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented"); 638 if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented");
639 JVM_END 639 JVM_END
640 640
641 // Common implementation for JVM_FindClassFromBootLoader and 641
642 // JVM_FindClassFromLoader 642 // Returns a class loaded by the bootstrap class loader; or null
643 static jclass jvm_find_class_from_class_loader(JNIEnv* env, const char* name, 643 // if not found. ClassNotFoundException is not thrown.
644 jboolean init, jobject loader, 644 //
645 jboolean throwError, TRAPS) {
646 // Java libraries should ensure that name is never null...
647 if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
648 // It's impossible to create this class; the name cannot fit
649 // into the constant pool.
650 if (throwError) {
651 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
652 } else {
653 THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
654 }
655 }
656 symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL);
657 Handle h_loader(THREAD, JNIHandles::resolve(loader));
658 jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
659 Handle(), throwError, THREAD);
660
661 if (TraceClassResolution && result != NULL) {
662 trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
663 }
664 return result;
665 }
666
667 // Rationale behind JVM_FindClassFromBootLoader 645 // Rationale behind JVM_FindClassFromBootLoader
668 // a> JVM_FindClassFromClassLoader was never exported in the export tables. 646 // a> JVM_FindClassFromClassLoader was never exported in the export tables.
669 // b> because of (a) java.dll has a direct dependecy on the unexported 647 // b> because of (a) java.dll has a direct dependecy on the unexported
670 // private symbol "_JVM_FindClassFromClassLoader@20". 648 // private symbol "_JVM_FindClassFromClassLoader@20".
671 // c> the launcher cannot use the private symbol as it dynamically opens 649 // c> the launcher cannot use the private symbol as it dynamically opens
679 // Thus a public/stable exported entry point is the right solution, 657 // Thus a public/stable exported entry point is the right solution,
680 // public here means public in linker semantics, and is exported only 658 // public here means public in linker semantics, and is exported only
681 // to the JDK, and is not intended to be a public API. 659 // to the JDK, and is not intended to be a public API.
682 660
683 JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env, 661 JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env,
684 const char* name, 662 const char* name))
685 jboolean throwError)) 663 JVMWrapper2("JVM_FindClassFromBootLoader %s", name);
686 JVMWrapper3("JVM_FindClassFromBootLoader %s throw %s", name, 664
687 throwError ? "error" : "exception"); 665 // Java libraries should ensure that name is never null...
688 return jvm_find_class_from_class_loader(env, name, JNI_FALSE, 666 if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
689 (jobject)NULL, throwError, THREAD); 667 // It's impossible to create this class; the name cannot fit
668 // into the constant pool.
669 return NULL;
670 }
671
672 symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL);
673 klassOop k = SystemDictionary::resolve_or_null(h_name, CHECK_NULL);
674 if (k == NULL) {
675 return NULL;
676 }
677
678 if (TraceClassResolution) {
679 trace_class_resolution(k);
680 }
681 return (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
690 JVM_END 682 JVM_END
691 683
692 JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, 684 JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
693 jboolean init, jobject loader, 685 jboolean init, jobject loader,
694 jboolean throwError)) 686 jboolean throwError))
695 JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name, 687 JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name,
696 throwError ? "error" : "exception"); 688 throwError ? "error" : "exception");
697 return jvm_find_class_from_class_loader(env, name, init, loader, 689 // Java libraries should ensure that name is never null...
698 throwError, THREAD); 690 if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
691 // It's impossible to create this class; the name cannot fit
692 // into the constant pool.
693 if (throwError) {
694 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
695 } else {
696 THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
697 }
698 }
699 symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL);
700 Handle h_loader(THREAD, JNIHandles::resolve(loader));
701 jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
702 Handle(), throwError, THREAD);
703
704 if (TraceClassResolution && result != NULL) {
705 trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
706 }
707 return result;
699 JVM_END 708 JVM_END
700 709
701 710
702 JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, 711 JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
703 jboolean init, jclass from)) 712 jboolean init, jclass from))
3917 jclass find_class_from_class_loader(JNIEnv* env, symbolHandle name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) { 3926 jclass find_class_from_class_loader(JNIEnv* env, symbolHandle name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) {
3918 // Security Note: 3927 // Security Note:
3919 // The Java level wrapper will perform the necessary security check allowing 3928 // The Java level wrapper will perform the necessary security check allowing
3920 // us to pass the NULL as the initiating class loader. 3929 // us to pass the NULL as the initiating class loader.
3921 klassOop klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL); 3930 klassOop klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL);
3931
3922 KlassHandle klass_handle(THREAD, klass); 3932 KlassHandle klass_handle(THREAD, klass);
3923 // Check if we should initialize the class 3933 // Check if we should initialize the class
3924 if (init && klass_handle->oop_is_instance()) { 3934 if (init && klass_handle->oop_is_instance()) {
3925 klass_handle->initialize(CHECK_NULL); 3935 klass_handle->initialize(CHECK_NULL);
3926 } 3936 }