Spring Framework
  1. Spring Framework
  2. SPR-10119

ContentNegotiatingViewResolver - Upgrade from 3.1 to 3.2 causes ClassCastException

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: 3.2 GA
    • Fix Version/s: 3.2.1
    • Component/s: Core, Web
    • Labels:
      None

      Description

      After having upgraded an existing web application from 3.1 to 3.2, the ContentNegotiatingViewResolver does not initialize correctly anymore and a ClassCastException exception is being thrown:

      java.lang.String cannot be cast to org.springframework.http.MediaType
      

      Using the new ContentNegotiationManager solves the issue. This issue is also described in the following forum thread:

      http://forum.springsource.org/showthread.php?133343-3-1-2-gt-3-2-issue-with-ContentNegotiatingViewResolver

        Activity

        Show
        Rossen Stoyanchev added a comment - Repro project added https://github.com/SpringSource/spring-framework-issues/tree/master/SPR-10019 .
        Hide
        Rossen Stoyanchev added a comment - - edited

        The issue doesn't seem to be related to Spring MVC but possibly to type conversion for arguments of type Map<String, MediaType>. The map should be initialized with MediaType instances via MediaTypeEditor. For some reason that works as expected for constructor arguments but not for properties. I've added two test classes ConstructorTests and PropertyTests that demonstrate the issue. PropertyTests fails:

        Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.springframework.http.MediaType
        	at org.springframework.web.accept.MappingMediaTypeFileExtensionResolver.<init>(MappingMediaTypeFileExtensionResolver.java:56)
        	at org.springframework.web.accept.AbstractMappingContentNegotiationStrategy.<init>(AbstractMappingContentNegotiationStrategy.java:42)
        	at org.springframework.web.accept.PathExtensionContentNegotiationStrategy.<init>(PathExtensionContentNegotiationStrategy.java:74)
        	at org.springframework.web.accept.ContentNegotiationManagerFactoryBean.afterPropertiesSet(ContentNegotiationManagerFactoryBean.java:169)
        	at org.springframework.web.servlet.view.ContentNegotiatingViewResolver.afterPropertiesSet(ContentNegotiatingViewResolver.java:270)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)
        	... 39 more
        
        
        Show
        Rossen Stoyanchev added a comment - - edited The issue doesn't seem to be related to Spring MVC but possibly to type conversion for arguments of type Map<String, MediaType> . The map should be initialized with MediaType instances via MediaTypeEditor . For some reason that works as expected for constructor arguments but not for properties. I've added two test classes ConstructorTests and PropertyTests that demonstrate the issue. PropertyTests fails: Caused by: java.lang.ClassCastException: java.lang. String cannot be cast to org.springframework.http.MediaType at org.springframework.web.accept.MappingMediaTypeFileExtensionResolver.<init>(MappingMediaTypeFileExtensionResolver.java:56) at org.springframework.web.accept.AbstractMappingContentNegotiationStrategy.<init>(AbstractMappingContentNegotiationStrategy.java:42) at org.springframework.web.accept.PathExtensionContentNegotiationStrategy.<init>(PathExtensionContentNegotiationStrategy.java:74) at org.springframework.web.accept.ContentNegotiationManagerFactoryBean.afterPropertiesSet(ContentNegotiationManagerFactoryBean.java:169) at org.springframework.web.servlet.view.ContentNegotiatingViewResolver.afterPropertiesSet(ContentNegotiatingViewResolver.java:270) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483) ... 39 more
        Hide
        Rossen Stoyanchev added a comment -

        Phil Webb, could you take a look at this one?

        Show
        Rossen Stoyanchev added a comment - Phil Webb , could you take a look at this one?
        Hide
        Keesun Baik added a comment - - edited

        Rossen Stoyanchev I've looked at this issue and debuged it a little while, I found something wrong in afterPropertiesSet() in the ContentNegotiationManagerFactoryBean. More specifically, I think the real problem is in the CollectionUtils.mergePropertiesIntoMap() method.

        First of all, I've tested a bean that sets Map<String, MediaType> by property, and it works fine. However, your test(PropertyTests) didn't work. Second of all, as I described above, the below codes have a problem:

        ContentNegotiatingManagerFactoryBean.java
        List<ContentNegotiationStrategy> strategies = new ArrayList<ContentNegotiationStrategy>();
        
        Map<String, MediaType> mediaTypesMap = new HashMap<String, MediaType>();
        CollectionUtils.mergePropertiesIntoMap(this.mediaTypes, mediaTypesMap);
        
        if (this.favorPathExtension) {
        

        The CollectionUtils.mergePropertiesIntoMap() method ignores the Map's key/value's types. Even though, the mediaTypesMap's value type is MediaType but the merged result contains String type value. This one causes the ClassCastException in the MappingMediaTypeFileExtensionResolver's constructor.

        It would be better change the CollectionUtils's mergePropetiesIntoMap() method to use the properties and map's type properly or ContentNegotiationManagerFactoryBean's afterPropertiesSet() method to use those type well.

        I hope this bug get fixed soon.

        Thanks.

        Show
        Keesun Baik added a comment - - edited Rossen Stoyanchev I've looked at this issue and debuged it a little while, I found something wrong in afterPropertiesSet() in the ContentNegotiationManagerFactoryBean. More specifically, I think the real problem is in the CollectionUtils.mergePropertiesIntoMap() method. First of all, I've tested a bean that sets Map<String, MediaType> by property, and it works fine. However, your test(PropertyTests) didn't work. Second of all, as I described above, the below codes have a problem: ContentNegotiatingManagerFactoryBean.java List<ContentNegotiationStrategy> strategies = new ArrayList<ContentNegotiationStrategy>(); Map< String , MediaType> mediaTypesMap = new HashMap< String , MediaType>(); CollectionUtils.mergePropertiesIntoMap( this .mediaTypes, mediaTypesMap); if ( this .favorPathExtension) { The CollectionUtils.mergePropertiesIntoMap() method ignores the Map's key/value's types. Even though, the mediaTypesMap's value type is MediaType but the merged result contains String type value. This one causes the ClassCastException in the MappingMediaTypeFileExtensionResolver's constructor. It would be better change the CollectionUtils's mergePropetiesIntoMap() method to use the properties and map's type properly or ContentNegotiationManagerFactoryBean's afterPropertiesSet() method to use those type well. I hope this bug get fixed soon. Thanks.
        Hide
        Rossen Stoyanchev added a comment -

        Keesun Baik, thanks for providing this analysis. The fix version is set for 3.2.1 so it'll be fixed soon.

        Show
        Rossen Stoyanchev added a comment - Keesun Baik , thanks for providing this analysis. The fix version is set for 3.2.1 so it'll be fixed soon.
        Hide
        Rossen Stoyanchev added a comment -

        This should now be fixed with 9f9f1e

        Show
        Rossen Stoyanchev added a comment - This should now be fixed with 9f9f1e

          People

          • Assignee:
            Rossen Stoyanchev
            Reporter:
            Gunnar Hillert
            Last updater:
            Rossen Stoyanchev
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              1 year, 16 weeks ago