4

我有一个看起来像这样的 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脚本包含到脚本中,但是在构建时脚本的位置是未知的(即我不能硬编码脚本中的绝对文件路径或 java 进程的绝对路径与位置有关脚本将被存储)。

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

我试图定位调用脚本的位置,但我得到了错误

  No signature of method: MyObject.evaluate()

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

4

1 回答 1

3

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

但是,可能实现您想要的;使用 Groovy,没有那么多限制......

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

  1. 您的类中的 getClass()MyObject自然是指...MyObject类,因此您查找脚本位置的尝试将失败。您在正确的轨道上,但您需要使用周围的 Script 类来解析脚本位置。
  2. evaluate并没有真正按照你想象的方式工作。方法的结果evaluate是脚本的结果,而不是Script类的实例。解决此问题的一种方法是将方法重写CommonFunction为闭包属性。Binding在评估脚本时,这些属性将在 shell 对象中可用。

所以,通过这些重写,你最终会得到这样的结果:

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.

于 2013-03-13T20:46:53.030 回答