Closed
Description
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:
- Data binding with java.util.Optional: traversal of nested paths, detection of empty holders [SPR-12241] #16855 Data binding with java.util.Optional: traversal of nested paths, detection of empty holders
- NPE while try to use abstract beans with optional properties [SPR-14474] #19043 NPE while try to use abstract beans with optional properties