3

我正在尝试扩展一个 Eclipse 代码构建器(用于从 Hibernate VO 生成 DTO)——它使用 Groovy 作为其模板系统。

它用于创建 groovy 脚本的代码有点奇怪(不是我在 Groovy 文档中看到的),但它可以正常工作,主要是:

GroovyShell shell = new GroovyShell();
script = shell.parse(source);

然后,稍后:

Binding binding = (bindings == null ? new Binding() : new Binding(bindings));
Script scriptInstance = InvokerHelper.createScript(script.getClass(), binding);
scriptInstance.setProperty("out", out);
scriptInstance.run();
out.flush();

现在,这工作得很好,直到它引用一个不直接在项目中的对象。在脚本中,它遍历它正在处理的 Class 的属性——当它这样做时,Groovy 会查看所有方法,当它找不到某个方法参数的 Class 定义时,它就会出错。在这种情况下,当它发现任何对 Hibernate 的引用时,它就会死去,但我相信它会因为更多的东西而崩溃。它不需要对他们做任何事情,但如果不知道他们显然是什么,它就无法生存。

脚本似乎没有可以提供任何类路径信息的类加载器,所以我尝试将它提供给GroovyShell - 没有区别。

解决这个问题的正确方法是什么,以便 Groovy 解释器可以找到我的项目引用的 Jars?

4

3 回答 3

3

我遇到了这个确切的问题,并通过创建自己的 URLClassLoader 并使用反射调用受保护的方法来向 ClassPath 添加新路径来解决它

// Specify the path you want to add
URL url = new URL("file://path/to/classes/here");

// Create a new class loader as a child of the default system class loader
ClassLoader loader = new URLClassLoader(System.getClass().getClassLoader()); 

// Get the AddURL method and call it
Method method = URLClassLoader.class.getDeclaredMethod("addURL",new Class[]{URL.class});
method.setAccessible(true);
method.invoke(loader,new Object[]{ url });

GroovyShell shell = new GroovyShell( loader );
于 2009-04-08T04:41:43.990 回答
2

与@James 相同,无需使用反射即可完成,从某个文件夹加载所有 jar 文件:

URLClassLoader classLoader = new URLClassLoader( getExtraJarUrls(), getClass().getClassLoader() );
GroovyShell shell = new GroovyShell( classLoader, binding, compilerConfiguration );


private URL[] getExtraJarUrls() throws MalformedURLException
{
    logger.debug( "Loading extra jars from {}", EXTRA_JARS_DIR.getAbsolutePath() );
    URL[] result;
    File[] files = EXTRA_JARS_DIR.listFiles( new JarFilenameFilter() );
    if (files != null)
    {
        List<URL> urls = new ArrayList<URL>( files.length );
        for (File file : files)
        {
            urls.add( file.toURI().toURL() );
        }
        result = urls.toArray( new URL[urls.size()] );
    }
    else
    {
        result = new URL[0];
    }
    logger.debug( "Adding URLs to classloader: {}", Arrays.toString( result ) );
    return result;
}

private static class JarFilenameFilter implements FilenameFilter
{
    public boolean accept( File dir, String name )
    {
        return name.endsWith( ".jar" );
    }
}
于 2012-09-25T12:59:26.280 回答
1

我在尝试自动运行 Gant 脚本时遇到了同样的问题。我找到的解决方案是:

  1. 将 gant-starter.conf(或 groovy-starter.conf,如果它只是 groovy)从 $GROOVY_HOME/conf 复制到您自己的目录;

  2. 在那里添加“load [directory]”或“load [jar]”,如 javadocs 中所述到 org.codehaus.groovy.tools.LoaderConfiguration,在 Groovy 源代码分发中找到;

  3. 在启动 groovy 之前,将 groovy.starter.conf.override 系统属性设置为该文件的名称,例如 -Dgroovy.starter.conf.override=[filename]

于 2009-04-16T00:11:55.030 回答