Scripting 在应用程序中使用groovy脚本的最佳方法

Scripting 在应用程序中使用groovy脚本的最佳方法,scripting,groovy,Scripting,Groovy,我正在尝试在我的应用程序中使用groovy脚本。问题是GroovyScriptEngine#run总是编译脚本,即使它是在以前的运行中编译的,并且此后没有更改。即使我设置了物理输出文件夹以在配置中保存编译结果 解决这个问题的最佳方法是什么?对我来说,最理想的情况是,我可以将脚本与包含预编译结果的文件夹一起发送,而不进行编译(当然,除非修改脚本)不确定这是否有帮助,但可以使用编译器配置更改GroovyScriptEngine的行为(请参阅GroovyScriptEngine.)。有一个选项Comp

我正在尝试在我的应用程序中使用groovy脚本。问题是GroovyScriptEngine#run总是编译脚本,即使它是在以前的运行中编译的,并且此后没有更改。即使我设置了物理输出文件夹以在配置中保存编译结果


解决这个问题的最佳方法是什么?对我来说,最理想的情况是,我可以将脚本与包含预编译结果的文件夹一起发送,而不进行编译(当然,除非修改脚本)

不确定这是否有帮助,但可以使用编译器配置更改GroovyScriptEngine的行为(请参阅GroovyScriptEngine.)。有一个选项CompilerConfiguration.,可用于设置如果源发生更改,是否重新加载和重新编译源。您可以阅读有关编译器配置的更多信息(第282页)。

Grails1.3.5正在使用Groovy1.7.5。在该Groovy版本中,
GroovyScriptEngine.run(…)
调用以下方法:
createScript(String,Binding)
-->
loadScriptByName(String)
-->
isSourceNewer(ScriptCacheEntry)

isSourceNewer(ScriptCacheEntry)
定义为(很遗憾,我在web上没有找到匹配的源文件):

它实现了(奇怪的)逻辑“如果一个脚本有依赖项,它比缓存的脚本新(需要重新编译)”。这不是代码应该做的;它应该由修改时间决定

在中(对逻辑进行了大量更改),但现在,您需要将
GroovyScriptEngine
子类化,并覆盖
isSourceNewer(ScriptCacheEntry)
以自行修复逻辑



编辑:该错误已在Groovy 1.7.6中被删除因此,请尝试在您的Grails lib文件夹中使用Groovy 1.7.6。

我最后使用的解决方案(hack)是使用xstream流式输出scriptCache变量,并将其读回并在对象中设置它。

不确定此标志的作用,但问题是GroovyScriptEngine#isSourceNewer使用ScriptCacheEntry对象。顾名思义,它来自缓存(地图)。创建GroovyScript引擎时,此映射为空。No entry表示isSourceNewer返回true,触发compilationGood to know,但这不是我的问题。我的问题是条件“if(entry==null)返回true;”在ISourcenewer的开始。这意味着一个新的GroovyScriptEngine将始终编译该脚本,即使它是以前编译的,并且从那以后没有更改
protected boolean isSourceNewer(ScriptCacheEntry entry) 
    throws ResourceException {
    // ...

    for (String scriptName : entry.dependencies) {
        // ...
        return true; // without any further condition!
    }

    return false;
}