Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-4334

Method parameter names missing in compiled classes when using parameter in closure

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Duplicate
    • 1.6.8
    • 1.7.6, 1.8-beta-3
    • bytecode, Compiler
    • 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).

      Attachments

        1. MissingParameterNames.zip
          9 kB
          Soenke Sothmann

        Activity

          People

            blackdrag Jochen Theodorou
            sothmann Soenke Sothmann
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: