在运行时将Groovy脚本导入另一个Groovy脚本

时间:2013-03-13 15:27:19

标签: java groovy groovyshell

我有一个看起来像这样(当前)的Groovy文件。

main.groovy

import org.packages.mystuff.JavaClassIAmUsing;
public class MyObject {

    def rate(item){
        def o = evaluate(new File (new File(getClass().protectionDomain.codeSource.location.path).parent),"CommonFunctions.groovy");
        println o.whoami();

    }
}

我有另一个名为

的groovy文件

CommonFunctions.groovy

def whoami() {return 'no body';}

我正在尝试将 CommonFunctions 脚本包含在 main 脚本中,但是在构建时不知道脚本的位置(即我无法硬编码脚本中的绝对文件路径或java进程的absoulte路径与脚本的存储位置有关。

我所知道的是脚本将在一起或相对于调用脚本(比如子目录)的位置。

我试图尝试定位调用脚本位置,但是我收到了错误

  No signature of method: MyObject.evaluate()

考虑到在运行时使用 GroovyClassLoader.parseClass(File)方法访问主脚本,我如何重新编写此脚本。

1 个答案:

答案 0 :(得分:2)

我不确定你为什么要这样做,我认为制作一个CommonsFunctions类可以正常实例化并在任何地方使用都会更简单。

然而, 可能达到你想要的效果;使用Groovy,没有那么多限制......

您建议的解决方案存在两个问题:

    你的MyObject类中的
  1. getClass()自然是指MyObject类,所以你试图找到脚本的位置会失败。您已走上正轨,但需要使用周围的Script类解析脚本位置。
  2. evaluate并不像你想象的那样真正起作用。 evaluate方法的结果是脚本的结果,而不是Script类的实例。解决这个问题的一种方法是将CommonFunction中的方法重写为闭包属性。在评估脚本时,这些属性将在shell Binding对象中可用。
  3. 所以,通过这些重写,你最终会得到类似的东西:

    <强> main.groovy

    class MyObject {
        def scriptDir
    
        def rate(item) {
            def commonFunctionsScriptFile = new File(scriptDir, "CommonFunctions.groovy")
            def binding = new Binding()
            new GroovyShell(binding).evaluate(commonFunctionsScriptFile)
            println binding.variables.whoami()
        }
    }
    
    scriptFile = new File(getClass().protectionDomain.codeSource.location.path)
    new MyObject(scriptDir: scriptFile.parentFile).rate(null)
    

    此处,脚本文件位置在脚本中解析,而不是在内部类中解析。

    <强> CommonFunctions.groovy

    whoami = { 'no body' }
    

    这里,whoami不再是一个方法,而是一个将被添加到绑定的闭包属性。确保使用def为此属性添加前缀,从那时起它将是一个局部变量,而不是添加到绑定对象的属性。

    这些重写后的输出是预期的:no body