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

Closure passed to field annotation fails to find static method of the same class

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Information Provided
    • 3.0.9
    • None
    • Compiler, groovy-runtime
    • None

    Description

      Closure passed to field annotation fails to find static method of the same class if Compiled to dynamic code.

       

      Code example, which shows how the same code works for statically compiled class, but fails for precise copy compiled dynamically.

      import groovy.transform.CompileDynamic
      import groovy.transform.CompileStatic
      
      import java.lang.annotation.Retention
      import java.lang.annotation.RetentionPolicy
      
      @Retention(RetentionPolicy.RUNTIME)
      @interface TestInterface {
          Class<?> value();
      }
      
      @CompileStatic
      class TestStatic {
      
          @TestInterface({o -> method(o)})
          Map map
      
          static String method(Object o) {
              o?.toString()
          }
      
      }
      
      @CompileDynamic
      class TestDynamic {
      
          @TestInterface({o -> method(o)})
          Map map
      
          static String method(Object o) {
              o?.toString()
          }
      
      }
      
      class TestMain {
          static void main(String[] args) {
              TestStatic ts = new TestStatic()
              TestInterface tsi = ts.getClass().getDeclaredField("map").getAnnotation(TestInterface)
              Class<?> vcs = tsi.value()
              if (Closure.isAssignableFrom(vcs)) {
                  Closure closure = (Closure)vcs.newInstance(null, null)
                  println(closure.call("OK"))
              }
      
              TestDynamic td = new TestDynamic()
              TestInterface tdi = td.getClass().getDeclaredField("map").getAnnotation(TestInterface)
              Class<?> vcd = tdi.value()
              if (Closure.isAssignableFrom(vcd)) {
                  Closure closure = (Closure)vcd.newInstance(null, null)
                  println(closure.call("FAILURE")) // Will throw exception
                  // Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: grapp.TestDynamic$_closure1.method() is applicable for argument types: (String) values: [FAILURE]
              }
          }
      }
      
      

      Attachments

        Activity

          People

            emilles Eric Milles
            arixmkii Arthur Sengileyev
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: