我正在尝试使用GroovyClassLoader
从Java运行Groovy脚本。基本上,我所做的就是:
GroovyClassLoader groovyLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
clazz = groovyLoader.parseClass(myFile);
GroovyObject go = (GroovyObject) go.newInstance();
return go.invokeMethod("MyMethod", myObject);
问题在于,当我解析groovy文件时,即使类位于 Java 类路径中,我的导入也无法解析。如果我添加一行:
groovyLoader.addClasspath("MyclassPath");
然后一切正常(如果我们无法解决这个问题,这是我们的最后手段)。这让我觉得有两个不同的类路径,一个用于Java,另一个用于Groovy。但是,由于我将Java类加载器作为GroovyClassloader的构造函数参数传递,我认为如果在Groovy类路径中找不到类,则应该在Java中查找它们。
我错了吗?有人可以对此有所了解吗?
谢谢。
答案 0 :(得分:0)
经过大量测试后,我发现Java推出的Groovy确实与启动Java的类路径相同。 OP上的问题是由我们方面的配置问题引起的。
对于未来的读者,我推荐这个问题How to get classpath in Groovy?,它在调试过程中提供了很多帮助。
答案 1 :(得分:0)
在导入解析中遇到了类似的问题。 就我而言,切换到
new GroovyClassLoader(this.getClass().getClassLoader())
代替
new GroovyClassLoader(Thread.currentThread().getContextClassLoader())
解决了这个问题。
请注意,根据docs GroovyClassLoader()
等效于GroovyClassLoader(Thread.currentThread().getContextClassLoader())
:
公共GroovyClassLoader()使用以下命令创建一个GroovyClassLoader 当前线程的上下文类加载器作为父级。
我的实际情况是一个运行web应用程序的Tomcat实例,该实例应从类路径加载一个groovy类并从中运行一个函数,但是groovy类中的导入在运行时无法解析。在调试时,我注意到当前线程和当前类的类加载器是不同的。我还使用调试器评估功能来确定类加载器是否知道特定的类,例如:
this.getClass().getClassLoader().classes.stream().filter(c -> c.getName().contains("YourClassInQuestion")).collect(Collectors.toList())
here也解释了类加载器和线程类加载器之间的区别。
希望这会有所帮助。 谢谢。