spring-projects/spring-framework · error · IllegalArgumentException

Specify targetClass or targetObject in combination with…

Error message

Specify targetClass or targetObject in combination with targetField

What it means

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'.

Solutions

  1. Add a targetClass (for static fields) or targetObject (for instance fields) alongside targetField.
  2. Or drop targetField and use staticField='com.acme.Const.MAX' so the factory parses both pieces.
  3. Or rely on the bean name itself being 'com.acme.Const.MAX' (the factory uses it as staticField when nothing else is set).
  4. Re-read the FieldRetrievingFactoryBean javadoc to confirm the supported property combinations before reconfiguring.

Example fix

<!-- before: only targetField set -->
<bean id='f' class='o.s.b.f.config.FieldRetrievingFactoryBean'>
  <property name='targetField' value='MAX'/>
</bean>

<!-- after: use staticField with full class.field expression -->
<bean id='f' class='o.s.b.f.config.FieldRetrievingFactoryBean'>
  <property name='staticField' value='com.acme.Const.MAX'/>
</bean>
Defensive patterns

Strategy: validation

Validate before calling

FieldRetrievingFactoryBean fb = new FieldRetrievingFactoryBean();
if (fb.getTargetClass() == null && fb.getTargetObject() == null && fb.getTargetField() != null
        && fb.getStaticField() == null) {
    throw new IllegalArgumentException("targetField needs targetClass or targetObject");
}

Type guard

boolean needsCompanion = (targetField != null) && (targetClass == null) && (targetObject == null);

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/28206bbc61c40741. Report an issue: GitHub.

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.java:169

		this.beanName = StringUtils.trimAllWhitespace(BeanFactoryUtils.originalBeanName(beanName));
	}

	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
		this.beanClassLoader = classLoader;
	}


	@Override
	@SuppressWarnings("NullAway") // Dataflow analysis limitation
	public void afterPropertiesSet() throws ClassNotFoundException, NoSuchFieldException {
		if (this.targetClass != null && this.targetObject != null) {
			throw new IllegalArgumentException("Specify either targetClass or targetObject, not both");
		}

		if (this.targetClass == null && this.targetObject == null) {
			if (this.targetField != null) {
				throw new IllegalArgumentException(
						"Specify targetClass or targetObject in combination with targetField");
			}

			// If no other property specified, consider bean name as static field expression.
			if (this.staticField == null) {
				this.staticField = this.beanName;
				Assert.state(this.staticField != null, "No target field specified");
			}

			// Try to parse static field into class and field.
			int lastDotIndex = this.staticField.lastIndexOf('.');
			if (lastDotIndex == -1 || lastDotIndex == this.staticField.length()) {
				throw new IllegalArgumentException(
						"staticField must be a fully qualified class plus static field name: " +
						"for example, 'example.MyExampleClass.MY_EXAMPLE_FIELD'");
			}
			String className = this.staticField.substring(0, lastDotIndex);
			String fieldName = this.staticField.substring(lastDotIndex + 1);

View on GitHub (pinned to 69bf83ad71)