{"record":{"id":"2cb2b356ba2024be","repo":"spring-projects/spring-framework","slug":"targetfield-is-required","errorCode":null,"errorMessage":"targetField is required","messagePattern":"targetField is required","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.java","lineNumber":194,"sourceCode":"\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);\n\t\t\tthis.targetClass = ClassUtils.forName(className, this.beanClassLoader);\n\t\t\tthis.targetField = fieldName;\n\t\t}\n\n\t\telse if (this.targetField == null) {\n\t\t\t// Either targetClass or targetObject specified.\n\t\t\tthrow new IllegalArgumentException(\"targetField is required\");\n\t\t}\n\n\t\t// Try to get the exact method first.\n\t\tClass<?> targetClass = (this.targetObject != null ? this.targetObject.getClass() : this.targetClass);\n\t\tthis.fieldObject = targetClass.getField(this.targetField);\n\t}\n\n\n\t@Override\n\tpublic @Nullable Object getObject() throws IllegalAccessException {\n\t\tif (this.fieldObject == null) {\n\t\t\tthrow new FactoryBeanNotInitializedException();\n\t\t}\n\t\tReflectionUtils.makeAccessible(this.fieldObject);\n\t\tif (this.targetObject != null) {\n\t\t\t// instance field\n\t\t\treturn this.fieldObject.get(this.targetObject);\n\t\t}","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.java#L176-L212","documentation":"Thrown by FieldRetrievingFactoryBean.afterPropertiesSet() when a targetClass or targetObject has been set but the name of the field to read (targetField) was not. FieldRetrievingFactoryBean is a FactoryBean that exposes a Java field as a bean; once you point it at a class or instance, it cannot proceed without knowing which field to retrieve via Class.getField. Spring uses this guard at initialization time to fail fast rather than NPE'ing later during reflection.","triggerScenarios":"Calling setTargetClass(...) or setTargetObject(...) on a FieldRetrievingFactoryBean (or the equivalent XML <property name=\"targetClass\"/>) without a matching <property name=\"targetField\"/>. Equivalently, using <util:constant> style but only supplying targetClass. Note: if you supply staticField (the fully-qualified 'pkg.Class.FIELD' form) instead, targetField is parsed for you and this error is not hit.","commonSituations":"XML config that sets targetClass to a class but omits targetField (typo or copy-paste missing the field property). Java @Bean config that calls bean.setTargetClass(MyType.class) but forgets bean.setTargetField(\"MY_CONST\"). Migrating from the convenience staticField / bean-name shorthand to the explicit targetClass/targetField form and missing one property.","solutions":["Add the missing <property name=\"targetField\" value=\"FIELD_NAME\"/> alongside targetClass, or call setTargetField(\"FIELD_NAME\") in code.","Prefer the concise staticField form: <property name=\"staticField\" value=\"pkg.MyClass.MY_CONST\"/> (or set the bean id to that fully-qualified string and set nothing else).","For instance fields, set targetObject (a bean ref or inner bean) AND targetField together; for static fields, set targetClass AND targetField, but never both targetClass and targetObject."],"exampleFix":"// before (broken)\nFieldRetrievingFactoryBean fb = new FieldRetrievingFactoryBean();\nfb.setTargetClass(java.sql.Connection.class);\n// after\nFieldRetrievingFactoryBean fb = new FieldRetrievingFactoryBean();\nfb.setTargetClass(java.sql.Connection.class);\nfb.setTargetField(\"TRANSACTION_SERIALIZABLE\");\n// or simply:\n// fb.setStaticField(\"java.sql.Connection.TRANSACTION_SERIALIZABLE\");","handlingStrategy":"validation","validationCode":"FieldRetrievingFactoryBean fb = new FieldRetrievingFactoryBean();\nfb.setTargetClass(MyType.class);\nif (fb.getTargetField() == null || fb.getTargetField().isBlank()) {\n    throw new IllegalStateException(\"targetField must be set when targetClass/targetObject is set\");\n}\nfb.afterPropertiesSet();","typeGuard":"static boolean hasFieldTarget(FieldRetrievingFactoryBean fb) {\n    return (fb.getTargetClass() != null || fb.getTargetObject() != null)\n        && fb.getTargetField() != null && !fb.getTargetField().isBlank();\n}","tryCatchPattern":"try {\n    fb.afterPropertiesSet();\n} catch (IllegalArgumentException ex) {\n    if (ex.getMessage().contains(\"targetField is required\")) {\n        // log config error, set a default field, or fail fast\n    }\n    throw ex;\n}","preventionTips":["Prefer the staticField shorthand ('pkg.Class.FIELD') so targetField is derived automatically.","In code, set targetField immediately after targetClass/targetObject to avoid forgetting it.","Add an integration test that refreshes the context to catch missing-property errors at build time."],"tags":["spring","factory-bean","configuration","reflection","field-access"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}