2

我有一个库,允许客户端提供一个文本文件列表,每个文件都包含扩展 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,并且 A 类在 B 类之前被解析。

问题是 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。

4

1 回答 1

0

根据我对 Groovy 类加载器(在这方面与 Ant 和 beanshell 的类加载器的行为相似)的经验,您必须预先决定是否要使用默认的系统类加载器,在这种情况下,您需要将类路径构建到启动 Groovy 脚本的命令,或者另一方面,您仅在命令行类路径中指定 groovy jar,然后在自定义类加载器上的 Groovy 脚本的开头动态添加类。

您在问题中没有提供太多信息,但我的猜测是您在启动脚本之前将类“A”放在类路径上,然后尝试动态加载类“B”。据我所知,那是行不通的。

注意:我自己一直在试图弄清楚如何做这种事情。这似乎是可能的,但我还没有想通。

于 2012-04-30T18:01:21.087 回答