简体   繁体   English

未能将 Groovy 库正确加载到 Groovy shell 执行脚本中

[英]Failure to load properly Groovy library into Groovy shell executing script

My software used groovy.lang Java package to execute Groovy scripts from a shell, binding the variables in the script to Java objects.我的软件使用 groovy.lang Java 包从 shell 执行 Groovy 脚本,将脚本中的变量绑定到 Java 对象。

A typical script looks like:典型的脚本如下所示:

package packagename

// import Java classes


abstract class MyClass extends Script {
    def myfunction() {
    }
}

in this example, 'myfunction' will be called from the outside.在这个例子中,'myfunction' 将从外部调用。

The scripts (located at the file system) are loaded by the following sequence from Java - the code returns GroovyShell class instance:脚本(位于文件系统中)按以下顺序从 Java 加载 - 代码返回 GroovyShell 类实例:

GroovyClassLoader groovyClassLoader = new GroovyClassLoader(...)
File groovyFile = new File(groovyURL.toURI());
Class<?> groovyClass = groovyClassLoader.parseClass(groovyFile);
CompilerConfiguration groovyConfig = new CompilerConfiguration();
groovyConfig.setScriptBaseClass(groovyClass.getName());
return new GroovyShell(groovyClassLoader, new Binding(), groovyConfig);

My design goal is to add a Groovy library that can be shared between scripts My preference is to implement a class (adding lines into the existing script seems to be a hack).我的设计目标是添加一个可以在脚本之间共享的 Groovy 库我的偏好是实现一个类(在现有脚本中添加行似乎是一种黑客行为)。

I made a simple class representing the library code.我做了一个简单的类来表示库代码。 Right now, it looks like:现在,它看起来像:

package shared

class MySharedLib
{
    static def testFunction()
    {
        return "test";
    }
}

To make sure the class it loaded, I added a call to为了确保它加载的类,我添加了一个调用

groovyClassLoader.parseClass(groovyLibraryFile)

before loading the actual script by:在通过以下方式加载实际脚本之前:

groovyClassLoader.parseClass(groovyFile); groovyClassLoader.parseClass(groovyFile);

Now, from the script, I can call the library:现在,从脚本中,我可以调用库:

shared.MySharedLib.testFunction()

indeed return the string "test".确实返回字符串“test”。

However, when trying to do the import via:但是,当尝试通过以下方式进行导入时:

import shared.MySharedLib

in the script (before class definition) - I always got an error when loading the script:在脚本中(在类定义之前) - 加载脚本时我总是遇到错误:

Exception in thread "main" org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script754084858.groovy: 14: unable to resolve class shared.MySharedLib
 @ line 14, column 1.

Tried to modify the classpath, it did not help.试图修改类路径,它没有帮助。 I realize something is wrong with my setup.我意识到我的设置有问题。 Will appreciate any tip how to load a Groovy library in the correct way.将欣赏如何以正确的方式加载 Groovy 库的任何提示。

Max最大限度

Thanks for comments.感谢您的评论。 I think I understand the cause.我想我明白原因了。 It turns out that at some point, the "script" is being compiled using事实证明,在某些时候,“脚本”正在使用

GroovyClassLoader classLoader = new GroovyClassLoader(parentClassLoader);
GroovyCodeSource codeSource = new GroovyCodeSource(code, scriptClassName + ".groovy", "/groovy/script");
CompilationUnit cu = new CompilationUnit(classLoader);
cu.addSource(codeSource.getName(), codeSource.getScriptText());
cu.compile(CompilePhase.CLASS_GENERATION.getPhaseNumber());

The compilation fails when reaching the "import" statement, since the library class is not in the classpath, so it's unreachable.到达“import”语句时编译失败,因为库类不在类路径中,因此无法访问。

Calling classLoader.addClasspath(path) with the appropriate path solves the issue.使用适当的路径调用classLoader.addClasspath(path)可以解决该问题。 So the problem was related to compilation - not to execution.所以问题与编译有关 - 与执行无关。

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

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