Skip to content

Unable to define empty java.util.Optional bean in spring xml [SPR-14121] #18693

Closed
@spring-projects-issues

Description

@spring-projects-issues

Yibo Wang opened SPR-14121 and commented

A bean who refers to an empty java.util.Optional value cannot be created with Spring configuration xml.

In Spring config xml file I have:

<bean id="emptyOptional" class="java.util.Optional" factory-method="empty"/>

Then when the Spring config was loaded, it reported the following error:

 [junit] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emptyOptional' defined in URL [file:configuration/spring-configuration/components/observers.xml]: Bean instantiation via factory method failed; nested exception is java.lang.IllegalArgumentException: Optional value must be present
[junit]     at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
[junit]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
[junit]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
[junit]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
[junit]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
[junit]     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
[junit]     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
[junit]     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
[junit]     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
[junit]     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
[junit]     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
[junit]     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
[junit]     at com.amazon.gpi.componentTesting.ComponentTestContext.createContext(ComponentTestContext.java:140)
[junit]     at com.amazon.gpi.componentTesting.ComponentTestContext.<init>(ComponentTestContext.java:117)
[junit]     at com.amazon.gpi.componentTesting.ComponentTestContext.fromProfile(ComponentTestContext.java:59)
[junit]     at com.amazon.gpi.componentTesting.TestProfileRunner.<init>(TestProfileRunner.java:130)
[junit]     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[junit]     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[junit] Caused by: java.lang.IllegalArgumentException: Optional value must be present
[junit]     at org.springframework.util.Assert.isTrue(Assert.java:68)
[junit]     at org.springframework.beans.AbstractNestablePropertyAccessor$OptionalUnwrapper.unwrap(AbstractNestablePropertyAccessor.java:1049)
[junit]     at org.springframework.beans.AbstractNestablePropertyAccessor.setWrappedInstance(AbstractNestablePropertyAccessor.java:207)
[junit]     at org.springframework.beans.BeanWrapperImpl.setWrappedInstance(BeanWrapperImpl.java:138)
[junit]     at org.springframework.beans.AbstractNestablePropertyAccessor.setWrappedInstance(AbstractNestablePropertyAccessor.java:194)
[junit]     at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:595)

Looks like spring tried to extract the nested value of the Optional class and use that to assign to the bean which was not what I intended. (What I tried to do was to have both empty Optional and present Optional and later conditionally choose to use one of them. So if spring did not extract the nested value, it would just work (like if the Optional is from Guava.))

Thanks


Affects: 4.2.4

Issue Links:

Referenced from: commits 0864834, 5c1d3fc, 157dcab

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions