我正在尝试扩展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的项目?
答案 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脚本时遇到同样的问题。我找到的解决方案是:
复制gant-starter.conf(或 groovy-starter.conf如果只是 groovy)从$ GROOVY_HOME / conf到你的 自己的目录;
添加“load [directory]”或 “加载[jar]”,如中所述 javadocs到 org.codehaus.groovy.tools.LoaderConfiguration, 在Groovy源代码发布中找到;
在开始groovy之前 groovy.starter.conf.override系统 属性到该文件的名称, 喜欢 -Dgroovy.starter.conf.override = [文件名]