The fact is that global transform code transformations must be available at compilation time. Having a transformer in the bank was what I did first! But, as you said, this is a sloppy job. What you want to do is compile the ast conversion class before others go to the compilation stage. Here is what you do!
Transformer Preparation
Create a directory that is precompiled to the src folder! and add the Transformation class and classes (such as annotations) that the transformer uses in this directory with the correct packaging structure.
Then create the org.codehaus.groovy.transform.ASTTransformation file in the called precompiled/META-INF/services and you will have the following structure.
precompiled --amanu ----LoggingASTTransformation.groovy --META-INF ----services ------org.codehaus.groovy.transform.ASTTransformation
Then write the full name of the transformer in the file org.codehaus.groovy.transform.ASTTransformation , for the example above, the full name will be amanu.LoggingASTTransformation
Implementation
package amanu import org.codehaus.groovy.transform.GroovyASTTransformation import org.codehaus.groovy.transform.ASTTransformation import org.codehaus.groovy.control.CompilePhase import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.control.SourceUnit @GroovyASTTransformation(phase=CompilePhase.CANONICALIZATION) class TeamDomainASTTransformation implements ASTTransformation{ public void visit(ASTNode[] nodes, SourceUnit sourceUnit) { println ("*********************** VISIT ************") source.getAST()?.getClasses()?.each { classNode ->
compilation
After that you can go in two ways! The first approach is to put it in a jar, just like you! and the other is to use a strict script to compile it before others. To do this in grails, we use the _Events.groovy script.
You can do this from a plugin or main project, it does not matter. If it does not exist, create a file named _Events.groovy and add the following content.
The code is copied from reinhard-seiler.blogspot.com with changes
eventCompileStart = {target -> ... compileAST(pluginBasedir, classesDirPath) ... } def compileAST(def srcBaseDir, def destDir) { ant.sequential { echo "Precompiling AST Transformations ..." echo "src ${srcBaseDir} ${destDir}" path id: "grails.compile.classpath", compileClasspath def classpathId = "grails.compile.classpath" mkdir dir: destDir groovyc(destdir: destDir, srcDir: "$srcBaseDir/src/precompiled", classpathref: classpathId, stacktrace: "yes", encoding: "UTF-8") copy(toDir:"$destDir/META-INF"){ fileset(dir:"$srcBaseDir/src/precompiled/META-INF") } echo "done precompiling AST Transformations" } }
The previous script compiles the transformer before compiling others! This allows you to convert the transformer to convert domain classes.
Do not forget
If you use a class other than those added to your class path, you will also have to copy them first. The above script will compile everything in the precompiled directory, and you can also add classes that ast do not need, but are needed for this in this directory!
If you want to use the domain classes in the conversion, you can do a preliminary evenCompileEnd block evenCompileEnd ! But it will make things slower!