如何设置嵌入式Groovy脚本类路径?

时间:2009-04-07 17:19:10

标签: groovy eclipse-plugin classpath embedded-language

我正在尝试扩展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();

现在,这很好用,直到它命中对不直接在项目中的对象的引用。在脚本中,它遍历它正在处理的类的属性 - 当它执行此操作时,Groovy查看所有方法,当它找不到其中一个方法参数的类定义时,它就会崩溃。在这种情况下,当它找到任何对Hibernate的引用时它就会死亡,但我相信它会更多地被废弃。它不需要对它们做任何事情,但如果不知道它们显然是什么就无法生存。

Script似乎没有可以提供任何类路径信息的类加载器,因此我尝试将其提供给GroovyShell - 没有区别。

修复此问题的正确方法是什么,以便Groovy解释器可以找到引用Jars的项目?

3 个答案:

答案 0 :(得分:2)

我遇到了这个问题并通过创建我自己的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 );

答案 1 :(得分: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" );
    }
}

答案 2 :(得分:0)

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

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

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

  3. 在开始groovy之前 groovy.starter.conf.override系统 属性到该文件的名称, 喜欢 -Dgroovy.starter.conf.override = [文件名]