Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy AST Transformation does not get applied during Grails Compile, only during Auto-Reloading

I have written a Groovy AST Transformation which only runs for me when Grails auto-reloads the class it is to be applied to. If I clean the project and start the application using run-app, the AST transformation does not run. Touching the class so that grails auto-reloads results in the transformation running.

The annotation and ASTTransformation implementation are groovy classes located in the src/groovy directory in my Grails application. The annotation is used on domain classes, written in groovy in the domain directory.

Is it possible this is caused by the order the groovy files get compiled or when they are loaded by the classloader? If so, how do I ensure my ast transforamtion is compiled/loaded before the domain classes?

The annotation:

@Target([ElementType.TYPE])
@Retention(RetentionPolicy.RUNTIME)
@GroovyASTTransformationClass(["com.abc.annotation.SecuredObjectASTTransformation"])
public @interface SecuredObject {
}

The ASTTransforamtion implementation:

@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
class SecuredObjectASTTransformation implements ASTTransformation {

    @Override
    public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
        // add some new properties...
    }
}

The Grails version is 2.1.0.

like image 746
Dónal Boyle Avatar asked Jan 10 '13 21:01

Dónal Boyle


1 Answers

All the various src/groovy, src/java and grails-app/* files get compiled together in one go so the AST transform isn't available to the compiler at the point where it compiles your domain classes. However plugins get compiled in a separate pass before the app so one option might be to create a very simple plugin just to contain the annotation and the AST transform class and declare that as an inline plugin in BuildConfig

grails.plugin.location.'secured-objects' = '../secured-objects'

The transform will then be built in the plugin compilation pass and will be on the compiler classpath when it comes to build your domains.

like image 106
Ian Roberts Avatar answered Sep 19 '22 05:09

Ian Roberts