Groovy AST Transformation is not used during Grails compilation, only during startup

I wrote a Groovy AST Transformation, which only works for me when Grails automatically reloads the class to which it should be applied. If I clean up the project and run the application using run-app, the AST transformation fails. Touching the class so that automatic reloading of grails starts the conversion.

The annotation implementation and ASTTransformation are Groovy classes located in the src / groovy directory in my Grails application. Annotations are used for domain classes written in Groovy in the domain directory.

Is it possible that this is due to the compilation order of the Groovy files, or when they are loaded by the class loader? If so, how can I ensure that my ast transformation is compiled / loaded to domain classes?

Annotation:

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

Implementation of ASTTransforamtion:

 @GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION) class SecuredObjectASTTransformation implements ASTTransformation { @Override public void visit(ASTNode[] nodes, SourceUnit sourceUnit) { // add some new properties... } } 

Grails version is 2.1.0.

+6
source share
3 answers

AST conversions must be compiled before the project code. The easiest way to do this is to hook up the grails compilation event using a script. Check out this blog post on how to create a script with a new ant task to precompile the source code in the src / ast folder. http://reinhard-seiler.blogspot.com.au/2011/09/grails-with-ats-transformation-tutorial.html

If you have only a few transformations of AST, then this is by far the best approach. Creating a plugin or a separate project with a compiled bank is too much work for my needs.

+2
source

All of the various src/groovy , src/java and grails-app/* files come together in a single pass, so the AST conversion is not available to the compiler when compiling your domain classes. However, plugins are compiled in a separate pass before the application, so one option would be to create a very simple plugin to simply contain the annotation and AST conversion class and declare it as a built-in plugin in BuildConfig

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

Then the conversion will be built in the compilation pass of the plugin and will be in the path to the compiler class when it comes to creating your domains.

+4
source

Also, if you want to avoid annotations and apply them to each class, you can check my answer here !

The answer describes how to apply global ASTTransforms. You can apply the conversion in all classes that compile after the transformer.

0
source

All Articles