简体   繁体   English

从Java运行的Groovy脚本是否具有相同的类路径?

[英]Does a Groovy script run from Java have the same classpath?

I'm trying to run a Groovy script from Java using GroovyClassLoader . 我正在尝试使用GroovyClassLoader从Java运行Groovy脚本。 Basically, what I do is this: 基本上,我做的是这样的:

GroovyClassLoader groovyLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
clazz = groovyLoader.parseClass(myFile);
GroovyObject go = (GroovyObject) go.newInstance();
return go.invokeMethod("MyMethod", myObject);

The problem is that when I'm parsing the groovy file, my imports are not resolved even though the classes are in the Java classpath. 问题是,当我解析groovy文件时,即使类在Java类路径中,我的导入也无法解析。 If I add a line with: 如果我添加一行:

groovyLoader.addClasspath("MyclassPath");

then everything works fine (this is our last resort in case we are unable to figure this out). 然后一切正常(如果我们无法解决这个问题,这是我们的最后手段)。 This makes me think that there are two differents classpaths, one for Java and one for Groovy. 这让我觉得有两个不同的类路径,一个用于Java,另一个用于Groovy。 But still, since I'm passing the Java classloader as a constructor argument for the GroovyClassloader, I'd think that if the classes are not found on the Groovy classpath, they should be looked up in Java's. 但是,由于我将Java类加载器作为GroovyClassloader的构造函数参数传递,我认为如果在Groovy类路径中找不到类,则应该在Java中查找它们。

Am I wrong? 我错了吗? Can someone shed some light on this? 有人可以对此有所了解吗?

Thank you. 谢谢。

After lots of tests, I've figured out that the Groovy launched by Java has indeed the same classpath of the launching Java. 经过大量测试后,我发现Java推出的Groovy确实与启动Java的类路径相同。 The problem on the OP was caused by a configuration problem on our side. OP的问题是由我们这方面的配置问题引起的。

For future readers, I recommend this question How to get classpath in Groovy? 对于未来的读者,我推荐这个问题如何在Groovy中获取类路径? which gave a lot of help during the debugging process. 这在调试过程中提供了很多帮助。

Encountered similar problem with imports resolution. 进口分辨率遇到类似的问题。 In my case switching to 在我的情况下切换到

new GroovyClassLoader(this.getClass().getClassLoader())

instead of 代替

new GroovyClassLoader(Thread.currentThread().getContextClassLoader())

fixed the problem. 解决了这个问题。

Note that according to the docs GroovyClassLoader() is equivalent to GroovyClassLoader(Thread.currentThread().getContextClassLoader()) : 请注意,根据文档, GroovyClassLoader()等效于GroovyClassLoader(Thread.currentThread().getContextClassLoader())

public GroovyClassLoader() creates a GroovyClassLoader using the current Thread's context Class loader as parent. public GroovyClassLoader()使用当前Thread的上下文类加载器作为父级创建GroovyClassLoader。

My actual situation was a Tomcat instance running a webapp which was supposed to load a groovy class from classpath and run a function from it, however the imports in groovy class failed to resolve at runtime. 我的实际情况是运行webapp的Tomcat实例,它应该从类路径加载一个groovy类并从中运行一个函数,但groovy类中的导入在运行时无法解析。 While debugging I noticed that classloaders for current thread and current class were different. 调试时我注意到当前线程和当前类的类加载器是不同的。 I also used debugger evaluation feature to find out if a classloader is aware of particular class like so: 我还使用调试器评估功能来查明类加载器是否知道特定的类,如下所示:

this.getClass().getClassLoader().classes.stream().filter(c -> c.getName().contains("YourClassInQuestion")).collect(Collectors.toList())

Also here is an explanation of the difference between class and thread classloaders. 这里还解释了类和线程类加载器之间的区别。

Hope this helps. 希望这可以帮助。 Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM