我有一个库,允许客户端提供一个文本文件列表,每个文件包含一个扩展java类Z的类的groovy代码。例如文件'A.groovy'包含
package com.mypkg;
public class A extends Z {
@Override
public void someMethod() {
// do something A-ish
}
}
等
库编译其中的每一个并且(在这种情况下)将向客户端返回类型为Z的实例。
当客户需要这样的东西时,我的问题出现了:
package com.mypkg;
public class B extends A { // extends A!
@Override
public void someMethod() {
// do something B-ish instead of A-ish
}
}
其中B扩展A,并且在B类之前解析了A类。
问题是GroovyClassLoader似乎无法找到类A,即使它只是解析了A.这是编译脚本并创建实例的代码:
for (String fileName : listOfScriptFiles) {
InputStream in = getInputStreamFromFile(fileName);
CompilerConfiguration compConfig = new CompilerConfiguration();
GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread()
.getContextClassLoader(), compConfig);
Z service = null;
Class clazz = classLoader.parseClass(in);
service = (Z) clazz.newInstance();
return service;
}
有没有办法在运行时“注册”A类,以便当Groovy尝试编译B类时,它不会抱怨A类不存在?
更新
我实际上能够通过在遍历客户端代码列表的循环外实例化GroovyClassLoader来解决这个问题,因此解析A的类加载器与解析B的类加载器相同。
问题仍然存在,因为我可以想象一个案例,在某个人的代码的一部分中他们解析A,然后在一个完全不同的部分,同一个类加载器不可用,他们解析B。
答案 0 :(得分:0)
根据我对Groovy类加载器的经验(在这方面与Ant和beanshell的类加载器的行为类似),您必须事先决定是否要使用默认的系统类加载器,在这种情况下,您将构建classpath到启动Groovy脚本的命令,或者另一方面,你只在命令行类路径上指定groovy jar,然后在自定义类加载器的Groovy脚本的开头动态添加类。
您的问题中没有提供太多信息,但我的猜测是您在启动脚本之前将类“A”放在类路径上,然后尝试动态加载类“B”。据我所知,这不会起作用。
注意:我自己一直试图弄清楚如何做这种事情。似乎有可能,但我仍然没有想到它。