[BLOSSOM-226] Call to annotated method @RequestMapping on a template ends in Argument type mismatch Created: 19/Oct/15  Updated: 25/Jul/16  Resolved: 20/Nov/15

Status: Closed
Project: Blossom
Component/s: None
Affects Version/s: 3.0.2
Fix Version/s: 3.1.2

Type: Bug Priority: Major
Reporter: Ugo La Giorgia Assignee: Tobias Mattsson
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 7 x64
Tomcat 7
Magnolia 5.4.2
Spring 4.2.1


Attachments: Java Source File BlossomRequestMappingHandlerAdapter.java    
Issue Links:
causality
caused by BLOSSOM-167 Support Spring MVC 3.1 MVC handler me... Closed
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[ ]* Steps to reproduce, expected, and actual results filled
[ ]* Affected version filled
Date of First Response:

 Description   

Call to an annoted method @RequestMapping on a template ends in Argument type mismatch when I specify a parameter of type info.magnolia.context.Context

Spring resolves the Context beeing an object of type org.springframework.validation.support.BindingAwareModelMap rather than a an instance of MgnlContext.getInstance() thus resulting in a Argument type mismatch.

Here is the stack trace

HandlerMethod details: 
Controller [com.foo.bar.template.WebPage]
Method [public java.lang.String com.foo.bar.template.WebPage.handleRequest(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,info.magnolia.context.Context,javax.jcr.Node) throws javax.jcr.RepositoryException]
Resolved arguments: 
[0] [type=info.magnolia.module.blossom.support.ForwardRequestWrapper] [value=info.magnolia.module.blossom.support.ForwardRequestWrapper@20415821]
[1] [type=info.magnolia.cms.security.SecurityCallbackFilter$StatusSniffingResponseWrapper] [value=info.magnolia.cms.security.SecurityCallbackFilter$StatusSniffingResponseWrapper@2200ef12]
[2] [type=org.springframework.validation.support.BindingAwareModelMap] [value={}]
[3] [type=info.magnolia.audit.MgnlAuditLoggingContentDecoratorNodeWrapper] [value=node /Test]

    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:225)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:111)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    ... 141 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    ... 149 more


 Comments   
Comment by Tobias Mattsson [ 19/Oct/15 ]

Do you have BlossomHandlerMethodArgumentResolver configured?

Can you share you're blossom-servlet.xml or Java config equivalent?

The configuration should be:

  <bean class="info.magnolia.module.blossom.web.BlossomRequestMappingHandlerAdapter">
    <property name="customArgumentResolvers">
      <list>
        <bean class="info.magnolia.module.blossom.web.BlossomHandlerMethodArgumentResolver" />
      </list>
    </property>
    <!-- For @Valid - JSR-303 Bean Validation API -->
    <property name="webBindingInitializer">
      <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
        <property name="validator">
          <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
        </property>
      </bean>
    </property>
    <property name="redirectPatterns">
      <list>
        <value>website:*</value>
      </list>
    </property>
  </bean>
Comment by Ugo La Giorgia [ 19/Oct/15 ]

sorry about the unwanted changes...was trying to find a sutable presentation for the stack trace (first post...)

Comment by Tobias Mattsson [ 19/Oct/15 ]

I have reproduced the problem. It's caused by the order that RequestMappingHandlerAdapter initializes its resolvers in getDefaultArgumentResolvers. The custom Blossom resolver is added towards the end of the list.

Context and WebContext implements Map which makes org.springframework.web.method.annotation.MapMethodProcessor resolve the parameter to the model map.

Likewise User and MgnlUser are processed by org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver because they implement Principal.

The Blossom custom resolver needs to be invoked before these standard resolvers.

A workaround right now is to use the static MgnlContext.getContext(), MgnlContext.getWebContext() and MgnlContext.getUser() methods.

A workaround that would still allow using these types as parameters would be to inherit from BlossomRequestMappingHandlerAdapter, overload the afterPropertiesSet() method and rearrange the resolvers after having invoked super.afterPropertiesSet().

Thanks for reporting this.

Comment by Tobias Mattsson [ 19/Oct/15 ]

Attached proposed fix.

Comment by Ugo La Giorgia [ 20/Oct/15 ]

Here is the Java config in the configuration bean: (looks about the same but in Java )

public HandlerAdapter handlerAdapter() {
    BlossomRequestMappingHandlerAdapter handlerAdapter = new BlossomRequestMappingHandlerAdapter();
    handlerAdapter.setRedirectPatterns("website:*");

    handlerAdapter.setCustomArgumentResolvers(Collections.<HandlerMethodArgumentResolver>singletonList(new BlossomHandlerMethodArgumentResolver()));

    // For @Valid - JSR-303 Bean Validation API -->
    ConfigurableWebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
    bindingInitializer.setValidator(validatorFactory());
    handlerAdapter.setWebBindingInitializer(bindingInitializer);

    return handlerAdapter;
}

You're right about the workarounds... Forgot to include them in my original post!

What's the timeline for the release of version 3.1.2 ?

Comment by Ugo La Giorgia [ 20/Oct/15 ]

The proposed fix is working in my environment. Will use my build in the meantime.
I’ll be waiting the release of version 3.1.2...

Thank you!

Comment by Jan Haderka [ 25/Jul/16 ]

Bulk close of all old resolved tickets.

Generated at Sun Feb 11 23:31:24 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.