groovy
  1. groovy
  2. GROOVY-2982

GroovyClassLoader parseClass does not provide annotation support

    Details

    • Number of attachments :
      1

      Description

      I want to use annotated classes im my Groovy beans, but org.springframework.scripting.groovy.GroovyScriptFactory#getScriptedObject uses getGroovyClassLoader().parseClass call, and it returns class instance with no annotations attached.
      The same groovy

        Activity

        Hide
        Max Ishchenko added a comment -

        Sorry, pressed "add" accidentally.

        So, the same groovy file compiled with groovyc generated bytecode WITH annotations.

        After some investigation I found, that groovy.lang.GroovyClassLoader#parseClass method invokes
        int goalPhase = compile(Phases.CLASS_GENERATION),
        unit.compile(goalPhase);

        whereas FileSystemCompiler invokes unit.compile(), and it invokes compile((Phases.ALL)

        The annotation is present in AST in both cases. But it is lost when goalPhase = Phases.CLASS_GENERATION

        Show
        Max Ishchenko added a comment - Sorry, pressed "add" accidentally. So, the same groovy file compiled with groovyc generated bytecode WITH annotations. After some investigation I found, that groovy.lang.GroovyClassLoader#parseClass method invokes int goalPhase = compile(Phases.CLASS_GENERATION), unit.compile(goalPhase); whereas FileSystemCompiler invokes unit.compile(), and it invokes compile((Phases.ALL) The annotation is present in AST in both cases. But it is lost when goalPhase = Phases.CLASS_GENERATION
        Hide
        blackdrag blackdrag added a comment -

        But this not making much sense to me. class generation is the phase where the actual class is created. Without that part you won't get something to execute. The annotations are part of the generated class, thus the annotation processing must be part of the class generation or happen before that phase.

        The only reason I could imagine that the annotation is lost, is that you execute two different versions of Groovy.

        Show
        blackdrag blackdrag added a comment - But this not making much sense to me. class generation is the phase where the actual class is created. Without that part you won't get something to execute. The annotations are part of the generated class, thus the annotation processing must be part of the class generation or happen before that phase. The only reason I could imagine that the annotation is lost, is that you execute two different versions of Groovy.
        Hide
        Max Ishchenko added a comment -

        That's a testcase for the bug.
        It includes Intellij Idea project for your convenience.
        Run TestRuntimeCompilation and see that no annotations were generated in the bytecode
        Run TestPrecompiled and see that the annotation is present in a class file.

        The first testcase uses a GroovyScriptFactory for groovy bean definition, the second one uses precompiled groovy script put in classpath.

        Show
        Max Ishchenko added a comment - That's a testcase for the bug. It includes Intellij Idea project for your convenience. Run TestRuntimeCompilation and see that no annotations were generated in the bytecode Run TestPrecompiled and see that the annotation is present in a class file. The first testcase uses a GroovyScriptFactory for groovy bean definition, the second one uses precompiled groovy script put in classpath.
        Hide
        Max Ishchenko added a comment -

        Of course, you must also put spring.jar, groovy-all.jar and commons-logging.jar into lib folder.
        The testcase was run against groovy 1.5.6

        Show
        Max Ishchenko added a comment - Of course, you must also put spring.jar, groovy-all.jar and commons-logging.jar into lib folder. The testcase was run against groovy 1.5.6
        Hide
        Paul King added a comment -

        Replicated the test case with Groovy 1.6.3 and Spring 2.5.6.

        Show
        Paul King added a comment - Replicated the test case with Groovy 1.6.3 and Spring 2.5.6.
        Hide
        Paul King added a comment - - edited

        But this seems to work:

        def parsedClass = new GroovyClassLoader().parseClass('@Deprecated class Foo {}', 'Foo')
        println parsedClass.annotations.size() // => 1
        @Deprecated class Bar {}
        println Bar.annotations.size() // => 1
        
        Show
        Paul King added a comment - - edited But this seems to work: def parsedClass = new GroovyClassLoader().parseClass('@Deprecated class Foo {}', 'Foo') println parsedClass.annotations.size() // => 1 @Deprecated class Bar {} println Bar.annotations.size() // => 1
        Hide
        blackdrag blackdrag added a comment - - edited

        is the class we test in the provided test case really the groovy class, or is it some kind of proxy?

        Show
        blackdrag blackdrag added a comment - - edited is the class we test in the provided test case really the groovy class, or is it some kind of proxy?
        Hide
        Paul King added a comment -

        It's not the Groovy class but an instance of org.springframework.scripting.groovy.GroovyScriptFactory which of course has no annotations. Still pondering if there is an easy way to get the real object.

        Show
        Paul King added a comment - It's not the Groovy class but an instance of org.springframework.scripting.groovy.GroovyScriptFactory which of course has no annotations. Still pondering if there is an easy way to get the real object.
        Hide
        Paul King added a comment -

        If I use the recommended bean integration technique, I get the real object:

        <lang:groovy id="annotatedBean" script-source="scripts/AnnotatedGroovyClass.groovy"/>
        

        So, I think this issue is resolved. Please re-open if you believe there is still a bug remaining.

        Show
        Paul King added a comment - If I use the recommended bean integration technique, I get the real object: <lang:groovy id= "annotatedBean" script-source= "scripts/AnnotatedGroovyClass.groovy" /> So, I think this issue is resolved. Please re-open if you believe there is still a bug remaining.

          People

          • Assignee:
            Paul King
            Reporter:
            Max Ishchenko
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: