Gradle: Gradle compile of groovy should not include grab/grapes annotation transform

Created on 17 Dec 2016  路  3Comments  路  Source: gradle/gradle

Groovy files can have dependencies specified via grapes. Since the groovy classloader is not used when compiling in gradle, the grapes are basically useless once the groovy code is compiled via gradle.

The issue with this is that grapes still attempt to resolve, resulting in the dreaded java.lang.NoClassDefFoundError: org/apache/ivy/core/report/ResolveReport error or similar.

It is possible to workaround some of these issues at compile time, but not (I think) at runtime. In any case, it is actually quite easy to avoid the issues by changing gradle to not apply the grape transformations at compile-time.

For example, this would do the trick (example code in groovy):

CompilerConfiguration compilerConfig = new CompilerConfiguration()
Set disabledTransforms = ['groovy.grape.GrabAnnotationTransformation'] as Set
compilerConfig.setDisabledGlobalASTTransformations(disabledTransforms)

CompilationUnit unit = new CompilationUnit(compilerConfig, null, classLoader)

...then use that CompilationUnit to compile the code.

Expected Behavior

When compiling groovy scripts, grapes should be totally stripped, as they represent duplicate dependency info, and they will give errors when processed at runtime.

Current Behavior

Grape transforms are applied at compile-time, resulting in runtime error java.lang.NoClassDefFoundError: org/apache/ivy/core/report/ResolveReport

Context

Implementing this would significantly lower the friction of moving groovy scripts to gradle while still keeping those scripts accessible as simple groovy scripts executable via groovy.

Steps to Reproduce

Create a groovy script with a grape dependency. Create a gradle build (with same dependencies) to build the script, and attempt to create the jar (without removing the grape annotations). Ivy/ResolveReport errors ensue.

If you want, workaround the compile-time issues e.g. by http://stackoverflow.com/questions/18173908/error-compiling-a-groovy-project-using-grab-annotation. However, why should you have to? In addition, resolving compile-time issue doesn't remove the generated grape code - it just stops it from running at compile time. The code can still try to run when the jar main class is executed.

bug contributor

Most helpful comment

I was able to workaround the issue at compile-time and runtime with the following in my gradle file:

compileGroovy {
  groovyOptions.configurationScript = file("gradle/config.groovy")
}

... where gradle/config.groovy contents are:

withConfig(configuration) {
  configuration.setDisabledGlobalASTTransformations(['groovy.grape.GrabAnnotationTransformation'] as Set)
}

All 3 comments

I was able to workaround the issue at compile-time and runtime with the following in my gradle file:

compileGroovy {
  groovyOptions.configurationScript = file("gradle/config.groovy")
}

... where gradle/config.groovy contents are:

withConfig(configuration) {
  configuration.setDisabledGlobalASTTransformations(['groovy.grape.GrabAnnotationTransformation'] as Set)
}

Thanks @DukeyToo thats exactly what I was looking for.
I ended up modifying your solution slightly because I didn't want to commit a seperate config file just for gradle, so I did this:

compileGroovy {
    // Create temp file.
    File temp = File.createTempFile("config", ".groovy");

    // Delete temp file when program exits.
    temp.deleteOnExit();

    // Write to temp file
    BufferedWriter out = new BufferedWriter(new FileWriter(temp));
    out.write("""\
        withConfig(configuration) {
            configuration.setDisabledGlobalASTTransformations(['groovy.grape.GrabAnnotationTransformation'] as Set)
        }
    """.stripIndent());
    out.close();
    groovyOptions.configurationScript = temp
}

I was able to workaround the issue at compile-time _and_ runtime with the following in my gradle file:

compileGroovy {
  groovyOptions.configurationScript = file("gradle/config.groovy")
}

... where gradle/config.groovy contents are:

withConfig(configuration) {
  configuration.setDisabledGlobalASTTransformations(['groovy.grape.GrabAnnotationTransformation'] as Set)
}

This solution worked for me. Thanks a lot

Was this page helpful?
5 / 5 - 1 ratings