I have a few groovy classes in the same package ( com.company.config
) in a multi-modular java-8 project.
All used to inherit a java
interface ( MyInterface
), but some refactoring was needed so I created a groovy
abstract class which resides in the same package as the other scripts; it implements MyInterface
and is inherited by the other scripts.
Ever since this change, I can't seem to execute the scripts from java
code anymore.
In particular, GroovyClassLoader::parseClass(File)
throws:
org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed:<|C:\my_workspace\a_project_name\modules\module-setup\src\com\company\config\MyScript1Impl.groovy:
7: unable to resolve class com.company.config.AbstractGroovyClass
@ line 7, column 1.
import com.company.config.AbstractGroovyClass
^
At line 7, you can indeed find the import declaration
import com.company.config.AbstractGroovyClass
which I added (despite the class being in the same package) after the first time the same error was thrown and after I read this .
The Exception
is triggered in the following line in the java
code:
public Object getInstance(File sourceFile) {
try {
GroovyClassLoader gcl = new GroovyClassLoader();
Class clazz = gcl.parseClass(sourceFile); // << Here
Object inst = clazz.newInstance();
// ....
}
// ...
}
whereas I call this function with the following parameters
getInstance(
new File("./modules/module-setup/src/com/company/config/"
className + ".groovy" // className = "MyScript1Impl" in this case
)
);
As already stated, before the introduction of the abstract class, everything was working fine.
Why can't the groovy
class find its superclass in the same package, even with the import declaration?
This is the stack-trace of the internal calls:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed ...
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:946)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:593)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:542)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:254)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:195)
The rest stack trace is relative to the application calls so it's unhelpful.
Edit I
I noticed indeed that the GroovyClassLoader
does not know anything about other groovy
classes and where they are located so I just added "./modules/module-setup/src/com/company/config/"
in
GroovyClassLoader::addClassPath(String)
but I'm getting the same result as before.
The path is surely correct as the File
instance is created with it and can be opened by the class loader.
I resolved it temporarily by loading the superclass via GroovyClassLoader::parseClass
right before loading the actual inherited class.
final GroovyClassLoader gcl = new GroovyClassLoader();
// ...
// load superclass first
Class<?> abstractClass = gcl.parseClass(new File(classPath, "AbstractGroovyClass.groovy"));
// load the actual script
Class<?> clazz = gcl.parseClass(sourceFile);
It's definitely a bad answer as, if I had more groovy
classes on which I depend on, I would have to manually parse them one by one. But it works...
Hoping someone can give a better answer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.