Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Duplicate
-
1.6.8
-
None
-
Groovy 1.6.8, Windows XP 32Bit, Grails 1.2.2
Description
When you define a closure inside a method body, and inside the closure you directly access a method argument, parameter name of surrounding class is missing.
The parameter name of the method is correctly compiled into the class file if you assign the method parameter to a local variable and use this variable inside the closure.
This is a problem when you use Spring Security 3 to secure service methods.
I tried to annotate my groovy service method like this:
@PreAuthorize("hasPermission(#myArg, 'read')") Bar getBarFromFoo3(Foo myArg) { def criteria = Bar.createCriteria() List result = criteria { eq("foo", myArg) maxResults(1) } if (result.size() == 0) { return null } return result[0] }
The annotation should protect the argument "myArg". Spring Security fails to secure this method because it cannot find the parameter named "myArg".
Decompiling the class file reveals:
@PreAuthorize("hasPermission(#myArg, 'read')") public Bar getBarFromFoo3(Foo ???) {
the parameter name is missing (indicated by the three "?").
When I use a local variable for the parameter, it works:
@PreAuthorize("hasPermission(#myArg, 'read')") Bar getBarFromFoo4(Foo myArg) { Foo localMyArg = myArg def criteria = Bar.createCriteria() List result = criteria { eq("foo", localMyArg) maxResults(1) } if (result.size() == 0) { return null } return result[0] }
Decompiling the class file reveals:
@PreAuthorize("hasPermission(#myArg, 'read')") public Bar getBarFromFoo4(Foo myArg) {
Here you can see that the parameter name is correctly compiled into the class file.
You can see this using a decompiler like JD (http://java.decompiler.free.fr/?q=jdgui#downloads).