[英]How do I set an embedded Groovy scripts classpath?
I am trying to extend an Eclipse code builder (for generating DTOs from Hibernate VOs) - and it uses Groovy for its template system. 我正在尝试扩展Eclipse代码构建器(用于从Hibernate VO生成DTO),并且它将Groovy用于其模板系统。
The code it uses to create the groovy Script is a little weird (not what I see in the Groovy docs) but it works, mostly: 它用来创建groovy脚本的代码有点奇怪(不是我在Groovy文档中看到的),但是它可以正常工作,主要是:
GroovyShell shell = new GroovyShell();
script = shell.parse(source);
Then, later: 然后,稍后:
Binding binding = (bindings == null ? new Binding() : new Binding(bindings));
Script scriptInstance = InvokerHelper.createScript(script.getClass(), binding);
scriptInstance.setProperty("out", out);
scriptInstance.run();
out.flush();
Now, this works just fine, until it hits a reference to an object that is not directly in the project. 现在,这很好用,直到它找到对不直接在项目中的对象的引用。 In the script, it iterates through the properties of the Class that it is processing - when it does this, Groovy looks at all of the methods and when it can't find a Class definition for one of the method parameters, it craps out.
在脚本中,它遍历正在处理的Class的属性-当执行此操作时,Groovy会查看所有方法,而当它找不到方法参数之一的Class定义时,它将退出。 In this case, it's dying when it finds any references to Hibernate, but I'm sure it will crap out with a lot more.
在这种情况下,当它找到任何对Hibernate的引用时,它就死了,但是我敢肯定,它将提供更多的东西。 It doesn't need to do anything to them, but it can't live without knowing what they are apparently.
它不需要对他们做任何事情,但是如果不知道它们的表面情况就无法生存。
Script doesn't appear to have a classloader that I can supply any classpath info, so I tried providing it to the GroovyShell - no difference. 脚本似乎没有可提供任何类路径信息的类加载器,因此我尝试将其提供给GroovyShell-没什么区别。
What's the proper way to fix this so that the Groovy interpreter can find my projects referenced Jars? 解决此问题的适当方法是什么,以便Groovy解释器可以找到引用Jars的项目?
The same as @James can be done without using reflection, loading all jar files from a certain folder: 无需使用反射即可完成@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" );
}
}
I had this exact problem and solved it by creating my own URLClassLoader, and using reflection to call a protected method to add a new path to the ClassPath 我遇到了这个确切的问题,并通过创建自己的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 );
I'm having the same problem trying to automate Gant scripts running. 我在尝试自动运行Gant脚本时遇到了同样的问题。 The solution I found is:
我找到的解决方案是:
copy gant-starter.conf (or groovy-starter.conf if it's just groovy) from $GROOVY_HOME/conf to your own dir; 从$ GROOVY_HOME / conf复制gant-starter.conf(或groovy-starter.conf)到您自己的目录;
add "load [directory]" or "load [jar]" there, as described in javadocs to org.codehaus.groovy.tools.LoaderConfiguration, found in Groovy source distribution; 按照javadocs中的描述,在Groovy源代码分发中的org.codehaus.groovy.tools.LoaderConfiguration中添加“加载[目录]”或“加载[jar]”;
before starting groovy set groovy.starter.conf.override system property to the name of that file, like -Dgroovy.starter.conf.override=[filename] 在开始groovy之前,请将groovy.starter.conf.override系统属性设置为该文件的名称,例如-Dgroovy.starter.conf.override = [filename]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.