Closed spring-projects-issues closed 12 years ago
Burkhard Graves commented
Hi Jamie, I ran into the same problem - do you have a 'quick workaround' for the the not working 'filters="none"'?
Jamie Goodfellow commented
I made a copy of org.springframework.core.CollectionFactory and put it in my own JAR, and updated the createCollection method to be:
public static Collection createCollection(Class<?> collectionType, int initialCapacity) {
if (collectionType.isInterface()) {
if (List.class.equals(collectionType)) {
return new ArrayList(initialCapacity);
}
else if (SortedSet.class.equals(collectionType) || collectionType.equals(navigableSetClass)) {
return new TreeSet();
}
else if (Set.class.equals(collectionType) || Collection.class.equals(collectionType)) {
return new LinkedHashSet(initialCapacity);
}
else {
throw new IllegalArgumentException("Unsupported Collection interface: " + collectionType.getName());
}
}
else {
if (!Collection.class.isAssignableFrom(collectionType)) {
throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName());
}
else if(emptyListClass != null && emptyListClass.equals(collectionType)) {
return Collections.emptyList();
}
try {
return (Collection) collectionType.newInstance();
}
catch (Exception ex) {
throw new IllegalArgumentException("Could not instantiate Collection type: " + collectionType.getName());
}
}
}
Where emptyListClass is defined in the static constructor at the top: emptyListClass = Collections.emptyList().getClass();
This class overrides the Spring version in the class loader.
Alternatively, you could change your filters="none" to filters="permitAll" (which would allow everything through, but still apply filters), or you could stick with Spring 3.0.2. If anyone has any other/better workarounds, let me know!
Burkhard Graves commented
Hi Jamie, thanks for your help! I'll stick with 3.0.2 until 3.0.4 comes out - won't take long, I guess... ;-)
Juergen Hoeller commented
Fixed for 3.0.4 - will be available in tonight's 3.0.4 snapshot. Please give it an early try and let us know whether it works for you again!
Juergen
Chris Beams commented
Juergen - updated the affects and fix versions here so that this gets re-evaluated for RC1
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 {
}
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 https://github.com/spring-projects/spring-framework/commit/7eeb654eec3ac63c7a8a5df7ef279561bccff1e0, https://github.com/spring-projects/spring-framework/commit/e0d922d35202fdb9f309f2aeccd8293b09943ebd, https://github.com/spring-projects/spring-framework/commit/27b04036a9e6e7434bf3ef0942b417aa16b90574
Backported to: 3.0.7
3 votes, 8 watchers