0

我在一个多模块项目的同一个包 ( ) 中有几个类。com.company.config

所有这些都用于继承一个java接口 ( MyInterface),但需要进行一些重构,所以我创建了一个groovy抽象类,它与其他脚本位于同一个包中;它实现MyInterface并由其他脚本继承。

自从这个改变以来,我似乎不能再从java代码中执行脚本了。

特别是,GroovyClassLoader::parseClass(File)抛出:

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
^

在第 7 行,确实可以找到导入声明

import com.company.config.AbstractGroovyClass

在第一次抛出相同的错误之后以及在我阅读了这个之后,我添加了它(尽管类在同一个包中) 。

在代码的以下Exception行中触发java

public Object getInstance(File sourceFile) {
    try {
      GroovyClassLoader gcl = new GroovyClassLoader();
      Class clazz = gcl.parseClass(sourceFile); // << Here
      Object inst = clazz.newInstance();
      // ....
    }
    // ...
}

而我用以下参数调用这个函数

getInstance(
    new File("./modules/module-setup/src/com/company/config/"
         className + ".groovy" // className = "MyScript1Impl" in this case
    )
);

如前所述,在引入抽象类之前,一切正常。

groovy为什么即使有导入声明,类也不能在同一个包中找到它的超类?


这是内部调用的堆栈跟踪:

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)

其余的堆栈跟踪是相对于应用程序调用的,所以它没有帮助。


编辑我

我确实注意到他们对其他类以及它们所在的位置GroovyClassLoader一无所知,所以我只是添加了groovy"./modules/module-setup/src/com/company/config/"

GroovyClassLoader::addClassPath(String)

但我得到的结果和以前一样。

该路径肯定是正确的,因为File实例是用它创建的,并且可以由类加载器打开。

4

1 回答 1

0

GroovyClassLoader::parseClass我在加载实际继承的类之前通过加载超类暂时解决了这个问题。

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);

这绝对是一个糟糕的答案,因为如果我有更多groovy依赖的类,我将不得不一个一个地手动解析它们。但它的工作...

希望有人能给出更好的答案。

于 2018-02-06T14:15:24.753 回答