< prev index next >

src/hotspot/share/classfile/systemDictionary.cpp

Print this page
rev 49271 : 8199852: Print more information about class loaders in LinkageErrors.

*** 2140,2171 **** // if defining is true, then LinkageError if already in dictionary // if initiating loader, then ok if InstanceKlass matches existing entry void SystemDictionary::check_constraints(unsigned int d_hash, InstanceKlass* k, ! Handle class_loader, bool defining, TRAPS) { const char *linkage_error1 = NULL; const char *linkage_error2 = NULL; { Symbol* name = k->name(); ClassLoaderData *loader_data = class_loader_data(class_loader); MutexLocker mu(SystemDictionary_lock, THREAD); InstanceKlass* check = find_class(d_hash, name, loader_data->dictionary()); if (check != NULL) { ! // if different InstanceKlass - duplicate class definition, ! // else - ok, class loaded by a different thread in parallel, ! // we should only have found it if it was done loading and ok to use ! // dictionary only holds instance classes, placeholders ! // also holds array classes assert(check->is_instance_klass(), "noninstance in systemdictionary"); if ((defining == true) || (k != check)) { ! linkage_error1 = "loader (instance of "; ! linkage_error2 = "): attempted duplicate class definition for name: \""; } else { return; } } --- 2140,2177 ---- // if defining is true, then LinkageError if already in dictionary // if initiating loader, then ok if InstanceKlass matches existing entry void SystemDictionary::check_constraints(unsigned int d_hash, InstanceKlass* k, ! Handle class_loader, ! bool defining, TRAPS) { const char *linkage_error1 = NULL; const char *linkage_error2 = NULL; + const char *linkage_error3 = ""; + // Remember the loader of the similar class that is already loaded. + const char *existing_klass_loader_name = ""; + { Symbol* name = k->name(); ClassLoaderData *loader_data = class_loader_data(class_loader); MutexLocker mu(SystemDictionary_lock, THREAD); InstanceKlass* check = find_class(d_hash, name, loader_data->dictionary()); if (check != NULL) { ! // If different InstanceKlass - duplicate class definition, ! // else - ok, class loaded by a different thread in parallel. ! // We should only have found it if it was done loading and ok to use. ! // The dictionary only holds instance classes, placeholders ! // also hold array classes. assert(check->is_instance_klass(), "noninstance in systemdictionary"); if ((defining == true) || (k != check)) { ! linkage_error1 = "loader "; ! linkage_error2 = " attempted duplicate class definition for "; ! guarantee(check->class_loader() == class_loader(), "Per construction. Else report the other loader."); } else { return; } }
*** 2174,2205 **** assert(ph_check == NULL || ph_check == name, "invalid symbol"); #endif if (linkage_error1 == NULL) { if (constraints()->check_or_update(k, class_loader, name) == false) { ! linkage_error1 = "loader constraint violation: loader (instance of "; ! linkage_error2 = ") previously initiated loading for a different type with name \""; } } } // Throw error now if needed (cannot throw while holding // SystemDictionary_lock because of rank ordering) if (linkage_error1) { ResourceMark rm(THREAD); ! const char* class_loader_name = loader_name(class_loader()); ! char* type_name = k->name()->as_C_string(); ! size_t buflen = strlen(linkage_error1) + strlen(class_loader_name) + ! strlen(linkage_error2) + strlen(type_name) + 2; // +2 for '"' and null byte. ! char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); ! jio_snprintf(buf, buflen, "%s%s%s%s\"", linkage_error1, class_loader_name, linkage_error2, type_name); ! THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); } } - // Update class loader data dictionary - done after check_constraint and add_to_hierachy // have been called. void SystemDictionary::update_dictionary(unsigned int d_hash, int p_index, unsigned int p_hash, InstanceKlass* k, --- 2180,2218 ---- assert(ph_check == NULL || ph_check == name, "invalid symbol"); #endif if (linkage_error1 == NULL) { if (constraints()->check_or_update(k, class_loader, name) == false) { ! linkage_error1 = "loader constraint violation: loader "; ! linkage_error2 = " wants to load class "; ! linkage_error3 = ". A different class with the same name was previously loaded by "; ! Klass *existing_klass = constraints()->find_constrained_klass(name, class_loader); ! if (existing_klass->class_loader() != class_loader()) { ! existing_klass_loader_name = ! java_lang_ClassLoader::describe_external(existing_klass->class_loader()); ! } } } } // Throw error now if needed (cannot throw while holding // SystemDictionary_lock because of rank ordering) if (linkage_error1) { ResourceMark rm(THREAD); ! stringStream ss; ! ss.print("%s", linkage_error1); ! ss.print("%s", java_lang_ClassLoader::describe_external(class_loader())); ! ss.print("%s", linkage_error2); ! ss.print("%s", k->external_name()); ! ss.print("%s", linkage_error3); ! ss.print("%s", existing_klass_loader_name); ! ss.print("."); ! THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string()); } } // Update class loader data dictionary - done after check_constraint and add_to_hierachy // have been called. void SystemDictionary::update_dictionary(unsigned int d_hash, int p_index, unsigned int p_hash, InstanceKlass* k,
*** 3091,3104 **** _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); NOT_PRODUCT(SystemDictionary::verify()); } ! // caller needs ResourceMark const char* SystemDictionary::loader_name(const oop loader) { ! return ((loader) == NULL ? "<bootloader>" : ! InstanceKlass::cast((loader)->klass())->name()->as_C_string()); } // caller needs ResourceMark const char* SystemDictionary::loader_name(const ClassLoaderData* loader_data) { return (loader_data->class_loader() == NULL ? "<bootloader>" : --- 3104,3125 ---- _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); NOT_PRODUCT(SystemDictionary::verify()); } ! // Return string to give helpful intformation about a classloader. ! // Caller needs ResourceMark. const char* SystemDictionary::loader_name(const oop loader) { ! #if INCLUDE_CDS ! if (DumpSharedSpaces) { ! // Describe_external() calls assert(is_instance...) in various places, ! // which may fail with DumpSharedSpaces. ! if ((loader) == NULL) return "<bootloader>"; ! return InstanceKlass::cast((loader)->klass())->name()->as_C_string(); ! } ! #endif ! return java_lang_ClassLoader::describe_external(loader); } // caller needs ResourceMark const char* SystemDictionary::loader_name(const ClassLoaderData* loader_data) { return (loader_data->class_loader() == NULL ? "<bootloader>" :
< prev index next >