java - 将 Groovy 脚本动态加载到应用服务器中

标签 java spring tomcat groovy

我有一个在 Tomcat 中运行的 Java Spring 应用程序,用于根据传入文件执行各种处理规则。由于文件类型和规则发生变化,我想使用 Groovy 动态加载新的/更改的功能,而不必每次都重新编译/重新启动 Java 应用程序。

遵循来自 Groovy documentation 的“在 Java 中动态加载和运行 Groovy 代码” ,

GroovyClassLoader gcl = new GroovyClassLoader();
Class clazz = gcl.parseClass(myStringwithGroovyClassSource, "SomeName.groovy");
Object aScript = clazz.newInstance();
MyInterface myObject = (MyInterface) aScript;
myObject.interfaceMethod();

我创建了实现 MyInterface 的 SomeName.groovy 版本,并修改了我的 Java 应用程序以创建该类的实例,如上所示。我知道我的 Groovy 文件被正确读取了,因为如果我打印出 myObject.getClass().toString,它会显示 SomeName.groovy 中定义的正确对象类型;然而,当它调用已实现的方法之一 (myObject.interfaceMethod()) 时,它什么都不做。

我已经在 Tomcat 之外的 Java 应用程序中测试了这种方法并且它有效,所以我不确定为什么在应用程序服务器内部运行它会导致它中断。此外,我已经确认 groovy-all-2.1.8.jar 包含在我的项目中。

提前感谢您提供的任何信息,这些信息可能会阐明动态加载失败的原因。

谢谢。

最佳答案

您使用的 parseClass() 方法根本不查看任何外部文件。相反,它将第一个 String 参数(在您的例子中为 myStringwithGroovyClassSource)当作它是 Groovy 源文件的文本内容,而第二个String 参数(在您的情况下是文字 "SomeName.groovy")好像它是该文件的名称。此方法根本不打开或解析任何 ACTUAL 文件。

要使此代码按原样工作,您必须预定义变量 myStringwithGroovyClassSource。整体效果看起来像这样:

def myStringwithGroovyClassSource = """
class SomeName implements MyInterface {
    def prop1 = 1, prop2 = 2
    def interfaceMethod() { println prop1 }
}
"""

interface MyInterface { def interfaceMethod() }
GroovyClassLoader gcl = new GroovyClassLoader()
Class clazz = gcl.parseClass(myStringwithGroovyClassSource, "SomeName.groovy")
Object aScript = clazz.newInstance()
MyInterface myObject = (MyInterface) aScript
myObject.interfaceMethod()

现在,另一方面,如果如您所说,您已经有一个名为 SomeFile.groovy 的外部未编译 Groovy 源文件,您希望通过 GroovyClassLoader 将其引入您的脚本中,那么您需要将您现有的代码更改为如下所示:

interface MyInterface { def interfaceMethod() }
GroovyClassLoader gcl = new GroovyClassLoader()
Class clazz = gcl.parseClass("SomeName.groovy" as File)
Object aScript = clazz.newInstance()
MyInterface myObject = (MyInterface) aScript
myObject.interfaceMethod()

如果文件中的代码在编译时是有效的,那么你应该可以毫无问题地让它工作。

关于java - 将 Groovy 脚本动态加载到应用服务器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26937029/

相关文章:

java - GUI actionPerformed valueChanged 问题

Spring Batch 'RunIdIncrementer' 未生成下一个值

java - 使用 spring 重新映射 Web 应用程序 (tomcat) 中的图像请求以获得绝对路径

jsp - Servlet 的 doGet 不是从 JSP 表单调用的

java - 如何从 Spring 中的 bean 中获取 bean 的 id?

具有上传 jar 文件和相对路径能力的 Tomcat 服务器

java - 字符串中子字符串出现的次数 (Java)

java - 通过 Rserve 将多维数组从 Java 分配给 R

java - MATLAB:Java String[] 转换

java - 为什么我们需要@Lookup,scope=prototype 有什么问题吗?