Method code too large
Symptoms
Compilation of Groovy code instrumented by Clover fails with an error like:
| Error Compilation error compiling [integration] tests: startup failed:
General error during class generation: Method code too large!
java.lang.RuntimeException: Method code too large!
at groovyjarjarasm.asm.MethodWriter.a(Unknown Source)
at groovyjarjarasm.asm.ClassWriter.toByteArray(Unknown Source)
at org.codehaus.groovy.control.CompilationUnit$16.call(CompilationUnit.java:807)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1047)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:583)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:561)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:538)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:517)
...
Cause
There is a 64kB limit of byte code of a single method. In some cases this limit may be hit, for instance when many AST transformation plugins are used.
A good example is a test method written in a Spock framework, having dozens of "when: / then:" blocks, which is first transformed by the Spock and next instrumented by Clover.
Resolution
1) Identify the large method in your code causing a problem (this may be hard as there's no information from a groovyc, even with --verbose or --verboseCompile). Reduce size of this method, e.g. by splitting it.
or
2) Identify which plugins used in your build perform heavy AST transformations. Check what AST annotations you're using in your code. Try disabling or reconfiguring these plugins or removing annotations.
or
3) Reduce instrumentation level performed by Clover from "statement" to "method". This will result in smaller overhead generated by Clover at the cost of the coverage recording accuracy - only method entries will be recorded.
<clover-setup instrumentationLevel="method"/>
See: Clover-for-Ant / clover-setup
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>clover-maven-plugin</artifactId> <!-- artifact was called maven-clover2-plugin before 4.1.1 -->
<configuration>
<instrumentation>method</instrumentation>
</configuration>
</plugin>
See: Clover-for-Maven / setup mojo
// grails-app/conf/BuildConfig.groovy:
clover {
setuptask = { ant, binding, plugin ->
ant.'clover-setup'(instrumentationLevel: "method",
initstring: "${binding.projectWorkDir}/target/clover/clover.db") {
}
}
}
See: Clover-for-Grails / Advanced setup configuration