{"id":"290305ea3a361223","repo":"spring-projects/spring-framework","slug":"failed-to-re-introspect-class-beanclass-getname","errorCode":null,"errorMessage":"Failed to re-introspect class [${beanClass.getName()}]","messagePattern":"Failed to re-introspect class \\[(.+?)\\]","errorType":"exception","errorClass":"FatalBeanException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java","lineNumber":400,"sourceCode":"\t\t\tpd = this.propertyDescriptors.get(StringUtils.uncapitalize(name));\n\t\t\tif (pd == null) {\n\t\t\t\tpd = this.propertyDescriptors.get(StringUtils.capitalize(name));\n\t\t\t}\n\t\t}\n\t\treturn pd;\n\t}\n\n\tPropertyDescriptor[] getPropertyDescriptors() {\n\t\treturn this.propertyDescriptors.values().toArray(PropertyDescriptorUtils.EMPTY_PROPERTY_DESCRIPTOR_ARRAY);\n\t}\n\n\tprivate PropertyDescriptor buildGenericTypeAwarePropertyDescriptor(Class<?> beanClass, PropertyDescriptor pd) {\n\t\ttry {\n\t\t\treturn new GenericTypeAwarePropertyDescriptor(beanClass, pd.getName(), pd.getReadMethod(),\n\t\t\t\t\tpd.getWriteMethod(), pd.getPropertyEditorClass());\n\t\t}\n\t\tcatch (IntrospectionException ex) {\n\t\t\tthrow new FatalBeanException(\"Failed to re-introspect class [\" + beanClass.getName() + \"]\", ex);\n\t\t}\n\t}\n\n}\n","sourceCodeStart":382,"sourceCodeEnd":405,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java#L382-L405","documentation":"FatalBeanException thrown from buildGenericTypeAwarePropertyDescriptor when constructing a GenericTypeAwarePropertyDescriptor raises IntrospectionException - i.e. re-introspecting a single property descriptor against its declaring class failed. This is a narrower failure than [164]: the overall BeanInfo was obtained, but Spring's generic-type-aware wrapper could not reconcile this particular descriptor's read/write methods.","triggerScenarios":"CachedIntrospectionResults building a GenericTypeAwarePropertyDescriptor for a property whose read and write methods have incompatible generic signatures or where setReadMethod/setWriteMethod on the descriptor raises IntrospectionException during construction.","commonSituations":"Generic bean with parameterized accessors where the type variables resolve inconsistently across an inheritance hierarchy; interface default methods combined with class methods producing an incompatible pair; rarely, classes woven by AspectJ or generated by Lombok @Builder/@Accessors producing non-standard accessor shapes.","solutions":["Read the cause for the offending descriptor name and method pair.","Make the read and write method signatures (including generics) consistent across the hierarchy.","If Lombok-generated, recompile with a current Lombok and verify accessor shapes with javap.","Exclude the offending property from introspection by removing or renaming one of the conflicting methods."],"exampleFix":"// before\npublic interface Repo<T> { T getEntity(); void setEntity(Object o); }\n// cause: incompatible generic pair on GenericTypeAwarePropertyDescriptor\n\n// after\npublic interface Repo<T> { T getEntity(); void setEntity(T o); }","handlingStrategy":"try-catch","validationCode":"// Detect generic incompatibility before relying on Spring introspection\njava.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(MyClass.class);\nfor (PropertyDescriptor pd : info.getPropertyDescriptors()) {\n    Class<?> rt = pd.getReadMethod() == null ? null : pd.getReadMethod().getReturnType();\n    Class<?> wt = pd.getWriteMethod() == null ? null\n        : pd.getWriteMethod().getParameterTypes()[0];\n    if (rt != null && wt != null && !rt.isAssignableFrom(wt) && !wt.isAssignableFrom(rt)) {\n        throw new IllegalStateException(\"Incompatible accessors on \" + pd.getName());\n    }\n}","typeGuard":"static boolean hasConsistentGenericAccessors(Class<?> c) {\n    try {\n        for (PropertyDescriptor pd : java.beans.Introspector.getBeanInfo(c).getPropertyDescriptors()) {\n            if (pd.getReadMethod() != null && pd.getWriteMethod() != null) {\n                Class<?> r = pd.getReadMethod().getReturnType();\n                Class<?> w = pd.getWriteMethod().getParameterTypes()[0];\n                if (!r.isAssignableFrom(w) && !w.isAssignableFrom(r)) return false;\n            }\n        }\n        return true;\n    } catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    return CachedIntrospectionResults.forClass(beanClass);\n} catch (FatalBeanException ex) {\n    if (ex.getMessage().startsWith(\"Failed to re-introspect\")) {\n        log.error(\"Re-introspection failed on {} - likely generic mismatch\", beanClass.getName(), ex.getCause());\n    }\n    throw ex;\n}","preventionTips":["Keep generic accessors consistent across inheritance hierarchies.","Recompile generated code (Lombok/MapStruct) when changing generic signatures.","Test introspection of parameterized beans explicitly.","Avoid mixing interface default methods with class methods that conflict on a property."],"tags":["introspection","generic-types","fatal-bean-exception","spring-beans"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}