Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional @RequestParam with required=false no longer works in Spring 3.0.4 (compared to 3.0.2) when Controller extends interface [SPR-7483] #12141

Closed
spring-projects-issues opened this issue Aug 23, 2010 · 21 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Grant Gochnauer opened SPR-7483 and commented

In order to work around CGLIB and AOP memory issues all of our MVC controllers extend Interfaces for proxying.

We have something like this in our interface:

@RequestMapping(value = "/contactus.htm", method = RequestMethod.POST)
 ModelAndView handleContactUsSubmit(HttpServletRequest request, HttpServletResponse response,
                                    @RequestParam(value = "pUrl", required = false) String promotionUrl, @ModelAttribute ContactUsModel model,
                                    Errors errors);

And in the class:

@ExposeSharedPageAttributes
    public ModelAndView handleContactUsSubmit( HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "pUrl", required = false) String promotionUrl, @ModelAttribute ContactUsModel model,
            Errors errors )
    {

This worked great in Spring 3.0.2. After upgrading to 3.0.4, I receive the following stack trace:

Caused by: org.springframework.web.bind.annotation.support.HandlerMethodInvocationException: Failed to invoke handler method [public final org.springframework.web.servlet.ModelAndView $Proxy100.handleContactUsSubmit(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String,com.roche.cwp.web.template.contactus.model.ContactUsModel,org.springframework.validation.Errors)]; nested exception is java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.
	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:181)
	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:427)
	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:415)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:788)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:717)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
	... 81 more
Caused by: java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.
	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.getRequiredParameterName(HandlerMethodInvoker.java:731)
	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestParam(HandlerMethodInvoker.java:480)
	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:340)
	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:171)
	... 86 more



Affects: 3.0.4

Referenced from: commits 284f98f

1 votes, 5 watchers

@spring-projects-issues
Copy link
Collaborator Author

Grant Gochnauer commented

This is in Websphere 6.1 with JDK5

@spring-projects-issues
Copy link
Collaborator Author

Grant Gochnauer commented

In my spring servlet xml, I have this defined:

<aop:aspectj-autoproxy proxy-target-class="false"/>

@spring-projects-issues
Copy link
Collaborator Author

Grant Gochnauer commented

If I change <aop:aspectj-autoproxy proxy-target-class="false"/> to <aop:aspectj-autoproxy proxy-target-class="true"/> - everything works OK but now we're back to using CGLIB and a much larger memory footprint.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Sep 8, 2010

Juergen Hoeller commented

This turned out as a regression caused by the fix for #11985. Fixed for 3.0.5 now to accommodate both scenarios.

Feel free to give tonight's 3.0.5 snapshot a try, and let me know whether it works for you...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Grant Gochnauer commented

Thank you! :)

@spring-projects-issues
Copy link
Collaborator Author

Grant Gochnauer commented

Confirmed fixed in: spring-framework-3.0.5.CI-804

@spring-projects-issues
Copy link
Collaborator Author

Ritesh commented

The exception reappeared as soon as I replaced Spring 3.0.5 jar files with 3.1 M2 jar files.

@spring-projects-issues
Copy link
Collaborator Author

Ritesh commented

I get this exception after upgrading to 3.1 M2:

java.lang.IllegalArgumentException: Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.web.method.annotation.support.AbstractNamedValueMethodArgumentResolver.updateNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:133)
at org.springframework.web.method.annotation.support.AbstractNamedValueMethodArgumentResolver.getNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:111)
at org.springframework.web.method.annotation.support.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:80)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:65)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:153)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:100)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:502)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:465)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:863)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:792)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:851)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:767)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

@spring-projects-issues
Copy link
Collaborator Author

Ralph Schaer commented

I got the same exception after upgrading from 3.1M1 to 3.1M2.
"java.lang.IllegalArgumentException: Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.

This is the controller class that has the problem.

@Controller
public class CustomerInfoController {
...
@RequestMapping(value = "/customerInfo", method = RequestMethod.GET)
@Transactional(readOnly = true)
@ResponseBody
public Map<String, Object> customerInfo(@RequestParam(value = "cid", required = false) String customerId) {
...
}
...
}

It works if I remove the @Transactional annotation.
Looks like M2 has a problem with proxied methods.

@spring-projects-issues
Copy link
Collaborator Author

Emmanuel Venisse commented

As explained in above comments, this issue is present into 3.1 M2

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Rossen, this is probably an issue with our refactored RequestMethodHandlerAdapter. It was broken and got fixed in 3.0.x but apparently reappeared in 3.1 M2.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Aug 9, 2011

Rossen Stoyanchev commented

A fix related to class-proxied controllers was added after 3.1 M2 (#13110). Both interface and class-based proxying should work with the latest code. Emmanuel, Ralph, and Ritesh would you mind giving 3.1.0.BUILD-SNAPSHOT a try? The maven repository is http://maven.springframework.org/snapshot.

@spring-projects-issues
Copy link
Collaborator Author

Emmanuel Venisse commented

ok, it is fixed in 3.1.0.BUILD-SNAPSHOT, thanks

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Okay thanks for confirming. It sounds like the issue noticed in 3.1 M2 is addressed but feel free to reopen if not. It was a problem with proxying controllers (rather than controllers with interfaces). Ralph's code sample above confirms that as well.

@spring-projects-issues
Copy link
Collaborator Author

Marnel J. Rodriguez commented

I am on 3.0.5.RELEASE and below is my interface code.

@PreAuthorize("hasAuthority('PERM_DOCTORS_NOTES_CREATE')")
@RequestMapping(value = "/patient/{pin}/doctors-notes/action", method = RequestMethod.POST, params = "draftBtn")
ModelAndView saveDraft(@PathVariable("pin") long pin,
@RequestParam(value = "formKey") String formKey,
@ModelAttribute(WebFormSupport.FORM_NAME) FormResultDto formResult, BindingResult result,
HttpSession httpSession, HttpServletRequest request);

And still I get the error below.

Handler execution resulted in exception org.springframework.web.bind.annotation.support.HandlerMethodInvocationException: Failed to invoke handler method [public abstract org.springframework.web.servlet.ModelAndView com.tmc.emr.web.template.docnotes.controller.DoctorsNotesActionController.saveDraft(java.lang.String,com.tmc.emr.workflow.model.FormResultDto,org.springframework.validation.BindingResult,javax.servlet.http.HttpSession,javax.servlet.http.HttpServletRequest)]; nested exception is java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.

If I remove the security context to disable the @PreAuthorize annotation, everything works well. But with the security context enabled. I get that error. My viewResolver is org.springframework.web.servlet.view.velocity.VelocityViewResolver

@spring-projects-issues
Copy link
Collaborator Author

Marnel J. Rodriguez commented

Maybe conflict on spring security AOP?

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Does the controller method have the method parameter annotations? They need to be on the class. You'll notice the example in the original description has them.

@spring-projects-issues
Copy link
Collaborator Author

Ashish Kulkarni commented

I am getting the same error in Spring 3.0.6 on Websphere 8.0.02
here is my code
for AJAX
$.getJSON("getStateForCountry",{country : $('#COUNTRYCD').val(), t: (new Date()).getTime() , ajax: 'true', cache:false, type:'POST'}, function(j){
var options = '';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].statecd + '">' + j[i].description + '</option>';
}
$("#STATECD").html(options);
updateCity();
}
);

here is my code in Spring

@RequestMapping(value = "/getStateForCountry")
public @ResponseBody
List<Xref_State> getStateForCountry(@RequestParam
String country) throws Exception {

    if (StringUtils.equalsIgnoreCase(StringUtils.trimToEmpty(country), "USA")) {
        return myDao.getStates();
    }
    return new ArrayList<Xref_State>();
}

@spring-projects-issues
Copy link
Collaborator Author

Ashish Kulkarni commented

here is my websphere log
[1/30/12 10:10:47:976 EST] 0000001d servlet E com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause springServlet: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.web.bind.annotation.support.HandlerMethodInvocationException: Failed to invoke handler method [public java.util.List com.tauck.controller.AirportController.getStateForCountry(java.lang.String) throws java.lang.Exception]; nested exception is java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:574)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1188)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:763)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:454)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:125)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:92)
at clime.messadmin.filter.MessAdminFilter.doFilter(MessAdminFilter.java:130)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:328)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:95)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:340)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:175)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:919)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1016)
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3703)
at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:304)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:962)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1662)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:195)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:452)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:511)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:305)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:276)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.requestComplete(WorkQueueManager.java:557)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.attemptIO(WorkQueueManager.java:607)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.workerRun(WorkQueueManager.java:984)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager$Worker.run(WorkQueueManager.java:1069)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1659)
Caused by: org.springframework.web.bind.annotation.support.HandlerMethodInvocationException: Failed to invoke handler method [public java.util.List com.tauck.controller.AirportController.getStateForCountry(java.lang.String) throws java.lang.Exception]; nested exception is java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:181)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669)
... 55 more
Caused by: java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.getRequiredParameterName(HandlerMethodInvoker.java:721)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestParam(HandlerMethodInvoker.java:480)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:340)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:171)
... 60 more

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Although you're getting the same exception, the original description is for a controller that implements an interface and is therefore wrapped with a JDK dynamic proxy. You don't have the required flag set to false either. So this is not the same issue. Perhaps you code is not compiled with debug symbols? You can add the parameter name to the @RequestParam annotation (i.e. @RequestParam("country") String country).

@spring-projects-issues
Copy link
Collaborator Author

Ashish Kulkarni commented

Hi
After changing my method like below, it worked you can close this ticket

@RequestMapping(value = "/getStateForCountry")
public @ResponseBody
List<Xref_State> getStateForCountry(@RequestParam
String country) throws Exception {

if (StringUtils.equalsIgnoreCase(StringUtils.trimToEmpty(country), "USA")) { return myDao.getStates(); }
return new ArrayList<Xref_State>();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants