-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Description
Jamie Goodfellow opened SPR-7293 and commented
Prior to 3.0.3, this class was capable of converting from a java.util.Collections$EmptyList to java.util.Collections$EmptyList. Starting from 3.0.3, this operation results in the exception: java.lang.IllegalArgumentException: Could not instantiate Collection type: java.util.Collections$EmptyList
The following Test case was verified to pass in 3.0.2 and fail in 3.0.3:
package org.springframework.core.convert.support;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.springframework.core.convert.TypeDescriptor;
public class CollectionToCollectionConverterTest {
@Test
public void testCollectionsEmptyList() throws Exception {
CollectionToCollectionConverter converter = new CollectionToCollectionConverter(new GenericConversionService());
TypeDescriptor type = new TypeDescriptor(getClass().getField("list"), Class.forName("java.util.Collections$EmptyList"));
converter.convert(list, type, type);
}
public List list = Collections.emptyList();
}
This specific situation is a problem because Spring Security uses this mechanism to convert the filterChainMap in the filterChainProxy, and elements with filters="none" set the filter chain to Collections.EMPTY_LIST. The Spring Security stack trace showing this error is:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.util.LinkedHashMap' to required type 'java.util.Map' for property 'filterChainMap'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "{/resources/=[], /ui/error/session*=[], /favicon.ico=[], /=[org.springframework.security.web.context.SecurityContextPersistenceFilter@a30589, org.springframework.security.web.authentication.logout.LogoutFilter@c07930, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@544b02, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@87286, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@96d92e, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@18c5b4f, org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter@1beb7ec, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1cfb56, org.springframework.security.web.session.SessionManagementFilter@b8f952, org.springframework.security.web.access.ExceptionTranslationFilter@1f88953, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1cbf6bb, org.springframework.security.web.authentication.switchuser.SwitchUserFilter@1b3a74d]}" from type 'java.util.LinkedHashMap' to type 'java.util.Map'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "[]" from type 'java.util.Collections$EmptyList' to type 'java.util.Collections$EmptyList'; nested exception is java.lang.IllegalArgumentException: Could not instantiate Collection type: java.util.Collections$EmptyList
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:574)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at com.truecontext.common.test.web.XmlWebApplicationContextLoader.loadContext(XmlWebApplicationContextLoader.java:47)
at com.truecontext.common.test.web.XmlWebApplicationContextLoader.loadContext(XmlWebApplicationContextLoader.java:1)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
... 24 more
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.util.LinkedHashMap' to required type 'java.util.Map' for property 'filterChainMap'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "{/resources/=[], /ui/error/session*=[], /favicon.ico=[], /=[org.springframework.security.web.context.SecurityContextPersistenceFilter@a30589, org.springframework.security.web.authentication.logout.LogoutFilter@c07930, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@544b02, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@87286, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@96d92e, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@18c5b4f, org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter@1beb7ec, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1cfb56, org.springframework.security.web.session.SessionManagementFilter@b8f952, org.springframework.security.web.access.ExceptionTranslationFilter@1f88953, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1cbf6bb, org.springframework.security.web.authentication.switchuser.SwitchUserFilter@1b3a74d]}" from type 'java.util.LinkedHashMap' to type 'java.util.Map'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "[]" from type 'java.util.Collections$EmptyList' to type 'java.util.Collections$EmptyList'; nested exception is java.lang.IllegalArgumentException: Could not instantiate Collection type: java.util.Collections$EmptyList
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:457)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:499)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:493)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1363)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1076)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
... 36 more
Caused by: org.springframework.core.convert.ConversionFailedException: Unable to convert value "{/resources/=[], /ui/error/session*=[], /favicon.ico=[], /=[org.springframework.security.web.context.SecurityContextPersistenceFilter@a30589, org.springframework.security.web.authentication.logout.LogoutFilter@c07930, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@544b02, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@87286, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@96d92e, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@18c5b4f, org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter@1beb7ec, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1cfb56, org.springframework.security.web.session.SessionManagementFilter@b8f952, org.springframework.security.web.access.ExceptionTranslationFilter@1f88953, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1cbf6bb, org.springframework.security.web.authentication.switchuser.SwitchUserFilter@1b3a74d]}" from type 'java.util.LinkedHashMap' to type 'java.util.Map'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "[]" from type 'java.util.Collections$EmptyList' to type 'java.util.Collections$EmptyList'; nested exception is java.lang.IllegalArgumentException: Could not instantiate Collection type: java.util.Collections$EmptyList
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:183)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:141)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:447)
... 42 more
Caused by: org.springframework.core.convert.ConversionFailedException: Unable to convert value "[]" from type 'java.util.Collections$EmptyList' to type 'java.util.Collections$EmptyList'; nested exception is java.lang.IllegalArgumentException: Could not instantiate Collection type: java.util.Collections$EmptyList
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:183)
at org.springframework.core.convert.support.MapToMapConverter.convert(MapToMapConverter.java:68)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:37)
... 45 more
Caused by: java.lang.IllegalArgumentException: Could not instantiate Collection type: java.util.Collections$EmptyList
at org.springframework.core.CollectionFactory.createCollection(CollectionFactory.java:256)
at org.springframework.core.convert.support.CollectionToCollectionConverter.convert(CollectionToCollectionConverter.java:61)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:37)
... 48 more
I believe this used to work because a check was made to see if the source was assignable to the target type. If so, the source was returned. I would either put this logic back in, or in the CollectionsFactory, specially handle the Collections$EmptyList list type.
Affects: 3.0.3, 3.0.6, 3.1 RC2
Referenced from: commits 7eeb654, e0d922d, 27b0403
Backported to: 3.0.7
3 votes, 8 watchers