Switching "groovy" dependency to "compile" leads to "Could not resolve class"

We are in the process of cleaning up our build concerning the 1.6-rc1 deprecation of the “groovy” configuration.

One of our modules - lets call it moduleA - contains classes that are using ‘@GroovyASTTransformation’ and ‘@GroovyASTTransformationClass’.

Some other module is using this module.

dependencies {
  groovy moduleA
}

works, but

dependencies {
  compile moduleA
}

fails with

startup failed:
General error during semantic analysis: Could not resolve class named moduleA.Foo
  java.lang.RuntimeException: Could not resolve class named moduleA.Foo

I suspect that this might be one of the cases mentioned in the deprecation warning:

In some cases, it may be necessary to additionally configure the ‘groovyClasspath’ property of GroovyCompile and Groovydoc tasks.

But, honestly, the prospect of manually managing a classpath is giving me shivers.

This should work out-of-the-box. Can you provide a reproducible example, ideally as a GitHub project?

With ‘groovy moduleA’, you are putting ‘moduleA’ onto the class path that’s used for loading the Groovy compiler. This should never be necessary (and never be done), as the Groovy compiler loads transforms and their dependencies from the regular compile class path. The necessity to do this might be caused by a bug in the transform implementation, but without more information it’s hard to say.

To look further into this, I would need a minimal reproducible example. Alternatively, you could try to work around by doing something like ‘compileGroovy.groovyClasspath += someConfigurationThatContainsModuleA’, mimicking what you used to do with ‘groovy moduleA’.

Will try to create an example. Just wanted to make sure that this is not expected behavior. Thanks.

Hi Peter.

I’ve just sent a zip with a small project reproducing the problem to your gmail address. Let me know if you received it and ask if you need more input/explanation.

You are running into a known Groovy problem (although it’s not Groovy’s fault). ‘Class.forName(String)’ internally uses ‘ClassLoader.getCallerClassLoader()’, which doesn’t work reliably for Groovy code (i.e. when ‘Class.forName’ is called from Groovy code). Just use ‘getClass().classLoader.loadClass(String)’ instead.

PS: Please use firstName.lastName@gradleware.com.

OK, will use that address next time. :slight_smile:

Thanks for that info. Wasn’t aware of that issue.

It would probably be a good tidbit for the documentation of the groovy configuration deprecation warning. Nothing should go wrong changing from groovy to compile/testCompile but if something goes wrong then chances are good that ‘Class.forName(String)’ is the culprit.

As always: thanks for the amazing support!