Upgrade Groovy version of a project from 2.5.13 to 3.0.9 . Everything seems to be working but the CodeNarc plugin shows an error when trying to compile classes that includes tag @Immutable . Error:
Compilation failed for [CustomCompilerPhaseSourceDecorator[SourceFile["ClassTaggedWithImmutable.groovy"]]]; org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during conversion: groovy.transform.AnnotationCollectorMode cannot be cast to groovy.transform.AnnotationCollectorMode
java.lang.ClassCastException: groovy.transform.AnnotationCollectorMode cannot be cast to groovy.transform.AnnotationCollectorMode
at org.codehaus.groovy.transform.ASTTransformationCollectorCodeVisitor.lambda$findCollectedAnnotations$1(ASTTransformationCollectorCodeVisitor.java:187)
at java.util.Optional.map(Optional.java:215)
at org.codehaus.groovy.transform.ASTTransformationCollectorCodeVisitor.findCollectedAnnotations(ASTTransformationCollectorCodeVisitor.java:187)
at org.codehaus.groovy.transform.ASTTransformationCollectorCodeVisitor.visitAnnotations(ASTTransformationCollectorCodeVisitor.java:93)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:49)
at org.codehaus.groovy.transform.ASTTransformationCollectorCodeVisitor.visitClass(ASTTransformationCollectorCodeVisitor.java:77)
at org.codehaus.groovy.transform.ASTTransformationVisitor.lambda$addPhaseOperations$1(ASTTransformationVisitor.java:206)
at org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:942)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:671)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:635)
at org.codehaus.groovy.control.CompilationUnit$compile$11.call(Unknown Source)
at org.codenarc.source.AbstractSourceCode.init(AbstractSourceCode.groovy:98)
at org.codenarc.source.AbstractSourceCode.getAst(AbstractSourceCode.groovy:85)
at org.codenarc.rule.AbstractAstVisitorRule.applyTo(AbstractAstVisitorRule.java:90)
at org.codenarc.rule.AbstractRule.applyTo(AbstractRule.java:143)
at org.codenarc.rule.Rule$applyTo.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codenarc.rule.Rule$applyTo.call(Unknown Source)
at org.codenarc.analyzer.AbstractSourceAnalyzer$_collectViolations_closure3.doCall(AbstractSourceAnalyzer.groovy:46)
at sun.reflect.GeneratedMethodAccessor2361.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:38)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
at org.codenarc.analyzer.AbstractSourceAnalyzer.measureRuleProcessingTime(AbstractSourceAnalyzer.groovy:58)
at sun.reflect.GeneratedMethodAccessor2359.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:193)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:61)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:66)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:194)
at org.codenarc.analyzer.AbstractSourceAnalyzer.collectViolations(AbstractSourceAnalyzer.groovy:44)
at org.codenarc.ant.AntFileSetSourceAnalyzer.processFile(AntFileSetSourceAnalyzer.java:188)
at org.codenarc.ant.AntFileSetSourceAnalyzer.access$000(AntFileSetSourceAnalyzer.java:44)
at org.codenarc.ant.AntFileSetSourceAnalyzer$1.run(AntFileSetSourceAnalyzer.java:176)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
This error is thrown for every single class tagged with @Immutable but this does not brake the codenarc task, it actually performs the code checking, and the build is successful at the end. This situation only happens when Groovy version is grater or equal to 3.0.0. Lower than that (2.x.x) the compilation goes normal.
Some info about the project: Gradle 6.9.1; Spring Boot 2.6.1; CodeNarc tool version 2.2.0 (it is used through CodeNarc Gradle plugin)
Some actions I have tried
- Use different versions of Groovy 3
- Upgrade Gradle version
- Manually set the Groovy version for CodeNarc plugin to use
- Use different versions of codenarc
- Manually define
ASTTransformationphase through@GroovyASTTransformation - Disable the plugin and enable it again using XML CodeNarc config file
- Modify compilationClasspath for codenarcMain
- Use the codenarc rule to avoid Stateless classes checking (this rule skips
@Immutableclasses) this actually skipped the Immutable classes but in terms of revision, but the compile error still shows the error. - Use codenarc Exclusion config parameter to manually force it to skip the classes. Happened the same that the previous item.
- Modify and play with different versions of
org.codehaus.groovy:groovy-all(currently it uses the same Groovy version).
CodeNarc plugin configuration inside build.gradle
codenarc {
toolVersion '2.2.0'
codenarcMain {
maxPriority1Violations = 0
maxPriority2Violations = 3
maxPriority3Violations = 10
}
codenarcIntegrationTest {
maxPriority1Violations = 0
maxPriority2Violations = 0
maxPriority3Violations = 0
}
sourceSets = [
sourceSets.main,
sourceSets.test,
sourceSets.integrationTest
]
}
codenarcMain {
compilationClasspath = sourceSets.main.compileClasspath + sourceSets.main.output
}
codenarcTest {
compilationClasspath = sourceSets.test.compileClasspath + sourceSets.test.output
}
codenarcIntegrationTest {
compilationClasspath = sourceSets.integrationTest.compileClasspath + sourceSets.integrationTest.output
}
It looks like the underlying problem occurs because you are including some "enhanced" rules in your CodeNarc ruleset. Those rules require that CodeNarc have the application classes being analyzed, as well as any referenced classes, on the classpath, and the way the Gradle CodeNarc plugin is executing is not including those.
See https://github.com/CodeNarc/CodeNarc/issues/680.
Then your setting the compilationClasspath is producing the error above.
Remove any enhanced rules from your ruleset: CloneWithoutCloneable, JUnitAssertEqualsConstantActualValue, MissingOverrideAnnotation, UnsafeImplementationAsMap, GrailsDomainGormMethods. And remove your compilationClasspath configuration.