GroovyClassLoader - 将已解析的类添加到classpath

时间:2012-04-30 17:50:26

标签: java groovy classpath classloader

我有一个库,允许客户端提供一个文本文件列表,每个文件包含一个扩展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。

1 个答案:

答案 0 :(得分:0)

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

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

注意:我自己一直试图弄清楚如何做这种事情。似乎有可能,但我仍然没有想到它。