简体   繁体   中英

Groovy class can't locate superclass in the same package

I have a few classes in the same package ( com.company.config ) in a multi-modular 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM