Method Parameter Names and Spring

Continuing on the previous blog entry about Constructor and method parameters and Java not retaining the parameter names at runtime – the previous entry was about constructor not retaining the parameter names and the implication of this for Contructor injections in Spring, here I will cover a few more scenarios where parameter names not being retained has implications with Spring:

1. Consider Spring MVC Controller method with a parameter to bind to a request parameter which is passed in:
 
 
 
 
 

@RequestMapping(value='/members/find')
 public String getMembersByName(@RequestParam String name){
  ...
  return 'list';
 }

Here the parameter ‘name’ has a @RequestParam annotation associated with it, which is in an indication to Spring MVC to bind a request parameter ‘name’ to this method parameter.

Since the parameter name is not retained at runtime, it is likely that an exception will be thrown by Spring:

Request processing failed; nested exception is java.lang.IllegalArgumentException: Name for argument type  not available, and parameter name i
nformation not found in class file either.

The fix here is simple, to either compile with debug options on which will retain the parameter names at runtime OR a better one is to simply indicate what the expected request parameter name is, as an argument to the @RequestParam annotation:

@RequestMapping(value='/members/find')
public String getMembersByName(@RequestParam('name') String name){
 return 'list';
}

2. Along the same lines consider another Spring MVC controller method, this time supporting URI template patterns:

@RequestMapping(value='/members/{id}', method=RequestMethod.GET)
public @ResponseBody Member get(@PathVariable Integer id){
 return this.memberDB.get(id);
}

Here the expectation is that if a request comes in with a uri of /members/20, then the id parameter will get bound with a value of 20, however since at runtime the parameter name of ‘id’ is not retained, the fix like in the previous case is either to compile with debug on, or to explicitly mention in the @PathVariable annotation what the expected pattern name is:

@RequestMapping(value='/members/{id}', method=RequestMethod.GET)
public @ResponseBody Member get(@PathVariable('id') Integer id){

3. A third example is with caching support in Spring with @Cacheable annotation. Consider a sample method annotated with @Cacheable:

@Cacheable(value='default', key='#param1.concat('-').concat(#param2)')
public String cachedMethod(String param1, String param2){
    return '' + new Random().nextInt();
}

Here the key is a Spring-EL expression, which instructs the keygenerator to generate the key by combining the argument of the first parameter of name param1 with argument to the second parameter with name param2. However the problem like before is that these names are not available at runtime.

One of the fixes, as before is to compile with debug symbols turned on. A second fix is to use placeholders to stand in for parameter index – a0 OR p0 for first parameter, a1 OR p1 for second parameter and so on, this way the @Cacheable key will look like this:

@Cacheable(value='default', key='#p0.concat('-').concat(#p1)')
public String cachedMethod(String param1, String param2){
    return '' + new Random().nextInt();
}

So in conclusion, a safe way to use Spring features that depend on method parameter names is to compile with debug on(-g or -g:var option of javac) or by explicitly passing in meta information that indicates what the parameter names are at runtime.
 

Reference: Method Parameter Names and Spring from our JCG partner Biju Kunjummen at the all and sundry blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


seven + 8 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books