671 jio_snprintf(buf, buflen, msg, method_type, sig, loader1_name, current, loader2_name, 672 target, failed_type_name); 673 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); 674 } 675 } 676 677 void LinkResolver::check_field_loader_constraints(Symbol* field, Symbol* sig, 678 Klass* current_klass, 679 Klass* sel_klass, TRAPS) { 680 Handle ref_loader(THREAD, current_klass->class_loader()); 681 Handle sel_loader(THREAD, sel_klass->class_loader()); 682 683 ResourceMark rm(THREAD); // needed for check_signature_loaders 684 Symbol* failed_type_symbol = 685 SystemDictionary::check_signature_loaders(sig, 686 ref_loader, sel_loader, 687 false, 688 CHECK); 689 if (failed_type_symbol != NULL) { 690 const char* msg = "loader constraint violation: when resolving field" 691 " \"%s\" the class loader %s of the referring class, " 692 "%s, and the class loader %s for the field's resolved " 693 "type, %s, have different Class objects for that type"; 694 char* field_name = field->as_C_string(); 695 const char* loader1_name = java_lang_ClassLoader::describe_external(ref_loader()); 696 char* sel = sel_klass->name()->as_C_string(); 697 const char* loader2_name = java_lang_ClassLoader::describe_external(sel_loader()); 698 char* failed_type_name = failed_type_symbol->as_C_string(); 699 size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1_name) + 700 strlen(sel) + strlen(loader2_name) + strlen(failed_type_name) + 1; 701 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); 702 jio_snprintf(buf, buflen, msg, field_name, loader1_name, sel, loader2_name, 703 failed_type_name); 704 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); 705 } 706 } 707 708 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info, 709 Bytecodes::Code code, TRAPS) { 710 711 Handle nested_exception; 712 Klass* resolved_klass = link_info.resolved_klass(); 713 714 // 1. For invokevirtual, cannot call an interface method 715 if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) { 716 ResourceMark rm(THREAD); 717 char buf[200]; 718 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", 719 resolved_klass->external_name()); 720 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 721 } 722 723 // 2. check constant pool tag for called method - must be JVM_CONSTANT_Methodref | 671 jio_snprintf(buf, buflen, msg, method_type, sig, loader1_name, current, loader2_name, 672 target, failed_type_name); 673 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); 674 } 675 } 676 677 void LinkResolver::check_field_loader_constraints(Symbol* field, Symbol* sig, 678 Klass* current_klass, 679 Klass* sel_klass, TRAPS) { 680 Handle ref_loader(THREAD, current_klass->class_loader()); 681 Handle sel_loader(THREAD, sel_klass->class_loader()); 682 683 ResourceMark rm(THREAD); // needed for check_signature_loaders 684 Symbol* failed_type_symbol = 685 SystemDictionary::check_signature_loaders(sig, 686 ref_loader, sel_loader, 687 false, 688 CHECK); 689 if (failed_type_symbol != NULL) { 690 const char* msg = "loader constraint violation: when resolving field" 691 " \"%s\" of type %s, the class loader %s of the current class, " 692 "%s, and the class loader %s for the field's defining " 693 "type, %s, have different Class objects for type %s"; 694 const char* field_name = field->as_C_string(); 695 const char* loader1_name = java_lang_ClassLoader::describe_external(ref_loader()); 696 const char* sel = sel_klass->external_name(); 697 const char* loader2_name = java_lang_ClassLoader::describe_external(sel_loader()); 698 const char* failed_type_name = failed_type_symbol->as_klass_external_name(); 699 const char* curr_klass_name = current_klass->external_name(); 700 size_t buflen = strlen(msg) + strlen(field_name) + 2 * strlen(failed_type_name) + 701 strlen(loader1_name) + strlen(curr_klass_name) + 702 strlen(loader2_name) + strlen(sel) + 1; 703 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); 704 jio_snprintf(buf, buflen, msg, field_name, failed_type_name, loader1_name, 705 curr_klass_name, loader2_name, sel, failed_type_name); 706 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); 707 } 708 } 709 710 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info, 711 Bytecodes::Code code, TRAPS) { 712 713 Handle nested_exception; 714 Klass* resolved_klass = link_info.resolved_klass(); 715 716 // 1. For invokevirtual, cannot call an interface method 717 if (code == Bytecodes::_invokevirtual && resolved_klass->is_interface()) { 718 ResourceMark rm(THREAD); 719 char buf[200]; 720 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", 721 resolved_klass->external_name()); 722 THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 723 } 724 725 // 2. check constant pool tag for called method - must be JVM_CONSTANT_Methodref |