{"record":{"id":"28206bbc61c40741","repo":"spring-projects/spring-framework","slug":"specify-targetclass-or-targetobject-in-combination","errorCode":null,"errorMessage":"Specify targetClass or targetObject in combination with targetField","messagePattern":"Specify targetClass or targetObject in combination with targetField","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.java","lineNumber":169,"sourceCode":"\t\tthis.beanName = StringUtils.trimAllWhitespace(BeanFactoryUtils.originalBeanName(beanName));\n\t}\n\n\t@Override\n\tpublic void setBeanClassLoader(ClassLoader classLoader) {\n\t\tthis.beanClassLoader = classLoader;\n\t}\n\n\n\t@Override\n\t@SuppressWarnings(\"NullAway\") // Dataflow analysis limitation\n\tpublic void afterPropertiesSet() throws ClassNotFoundException, NoSuchFieldException {\n\t\tif (this.targetClass != null && this.targetObject != null) {\n\t\t\tthrow new IllegalArgumentException(\"Specify either targetClass or targetObject, not both\");\n\t\t}\n\n\t\tif (this.targetClass == null && this.targetObject == null) {\n\t\t\tif (this.targetField != null) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\"Specify targetClass or targetObject in combination with targetField\");\n\t\t\t}\n\n\t\t\t// If no other property specified, consider bean name as static field expression.\n\t\t\tif (this.staticField == null) {\n\t\t\t\tthis.staticField = this.beanName;\n\t\t\t\tAssert.state(this.staticField != null, \"No target field specified\");\n\t\t\t}\n\n\t\t\t// Try to parse static field into class and field.\n\t\t\tint lastDotIndex = this.staticField.lastIndexOf('.');\n\t\t\tif (lastDotIndex == -1 || lastDotIndex == this.staticField.length()) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\"staticField must be a fully qualified class plus static field name: \" +\n\t\t\t\t\t\t\"for example, 'example.MyExampleClass.MY_EXAMPLE_FIELD'\");\n\t\t\t}\n\t\t\tString className = this.staticField.substring(0, lastDotIndex);\n\t\t\tString fieldName = this.staticField.substring(lastDotIndex + 1);","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.java#L151-L187","documentation":"Thrown as an IllegalArgumentException by FieldRetrievingFactoryBean.afterPropertiesSet when neither targetClass nor targetObject is set but a targetField is provided. Without a class or object there is nothing to read the field from, so the configuration is rejected; the intended path in this case is to use the staticField shorthand (or the bean name) so the factory can parse 'class.field'.","triggerScenarios":"Configuring FieldRetrievingFactoryBean with targetField set but neither targetClass nor targetObject. afterPropertiesSet reaches the 'both null' branch, sees targetField != null, and throws, telling the user to pair the field with a class or object (or use staticField).","commonSituations":"XML config that sets only targetField expecting the bean name to imply the class; misreading the docs and assuming targetField alone resolves a static constant; forgetting to also set staticField or targetClass; refactoring that removed the targetClass/targetObject line.","solutions":["Add a targetClass (for static fields) or targetObject (for instance fields) alongside targetField.","Or drop targetField and use staticField='com.acme.Const.MAX' so the factory parses both pieces.","Or rely on the bean name itself being 'com.acme.Const.MAX' (the factory uses it as staticField when nothing else is set).","Re-read the FieldRetrievingFactoryBean javadoc to confirm the supported property combinations before reconfiguring."],"exampleFix":"<!-- before: only targetField set -->\n<bean id='f' class='o.s.b.f.config.FieldRetrievingFactoryBean'>\n  <property name='targetField' value='MAX'/>\n</bean>\n\n<!-- after: use staticField with full class.field expression -->\n<bean id='f' class='o.s.b.f.config.FieldRetrievingFactoryBean'>\n  <property name='staticField' value='com.acme.Const.MAX'/>\n</bean>","handlingStrategy":"validation","validationCode":"FieldRetrievingFactoryBean fb = new FieldRetrievingFactoryBean();\nif (fb.getTargetClass() == null && fb.getTargetObject() == null && fb.getTargetField() != null\n        && fb.getStaticField() == null) {\n    throw new IllegalArgumentException(\"targetField needs targetClass or targetObject\");\n}","typeGuard":"boolean needsCompanion = (targetField != null) && (targetClass == null) && (targetObject == null);","tryCatchPattern":null,"preventionTips":["Pair targetField with targetClass (static) or targetObject (instance).","Use staticField='pkg.Cls.FIELD' as the single self-contained property.","Read the FieldRetrievingFactoryBean javadoc before mixing properties.","Add a config sanity test that exercises each FieldRetrievingFactoryBean."],"tags":["spring","factory-bean","configuration","static-field"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}