[英]Import a Groovy script into another Groovy Script at Runtime
I have a Groovy file that looks like this (currently). 我有一个看起来像这样(当前)的Groovy文件。
main.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();
}
}
i have another groovy file called 我有另一个groovy文件叫
CommonFunctions.groovy CommonFunctions.groovy
def whoami() {return 'no body';}
I'm trying to include the CommonFunctions script in to main script, BUT the location of the script are not known at build time (ie i can not hardcode a absolute file path in the script or absoulte path of the java process in relation to where the scripts will be stored). 我正在尝试将CommonFunctions脚本包含在主脚本中,但是脚本的位置在构建时是未知的(即我不能硬编码脚本中的绝对文件路径或java进程的absoulte路径相对于哪里脚本将被存储)。
All i know is that the scripts will be together or at a location relative to the calling script (say sub directory). 我所知道的是脚本将在一起或在相对于调用脚本的位置(比如子目录)。
I've attempted to try and location the calling script location, but i get the error 我试图尝试定位调用脚本位置,但我收到错误
No signature of method: MyObject.evaluate()
How can i referance this script, considering the main script is accessed at runtime using a GroovyClassLoader.parseClass(File) method. 考虑到在运行时使用GroovyClassLoader.parseClass(File)方法访问主脚本,我如何重新编写此脚本。
I'm not really sure why you want to do it this way, I think it would be much simpler to make a class of CommonsFunctions
that you could instantiate normally and use everywhere. 我不确定你为什么要这样做,我认为制作一类
CommonsFunctions
可以更简单,你可以正常实例化并在任何地方使用。
However, it is possible to achieve what you want; 但是, 有可能实现你想要的; with Groovy, there are not that many limitations...
有了Groovy,没有那么多限制......
There are two problems with your suggested solution: 建议的解决方案有两个问题:
MyObject
class naturally refers to ... the MyObject
class, so your attempt to find the location of the script will fail. MyObject
类中的getClass()自然地引用了MyObject
类,因此您尝试查找脚本的位置将失败。 You're on the right track, but you need to resolve the script location using the surrounding Script class. evaluate
doesn't really work the way you think it does. evaluate
并不像你认为的那样真正起作用。 The result of the evaluate
method is the result of the script, not an instance of the Script
class. evaluate
方法的结果是脚本的结果,而不是Script
类的实例。 One way to remedy this, is to rewrite the methods in CommonFunction
as closure properties. CommonFunction
的方法重写为闭包属性。 These properties will be available in the shell Binding
object when evaluating the script. Binding
对象中可用。 So, with these rewrites, you end up with something like this: 所以,通过这些重写,你最终会得到这样的结果:
main.groovy 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)
Here, the script file location is resolved in the script, not in the inner class. 这里,脚本文件位置在脚本中解析,而不是在内部类中解析。
CommonFunctions.groovy CommonFunctions.groovy
whoami = { 'no body' }
Here, whoami
is no longer a method, but a closure property which will be added to the binding. 在这里,
whoami
不再是一个方法,而是一个将被添加到绑定中的闭包属性。 Make sure that you don't prefix this property with def
, since then it will be a local variable instead of a property added to the binding object. 确保不使用
def
为此属性添加前缀,因为它将是一个局部变量而不是添加到绑定对象的属性。
Output after these rewrites is the expected: no body
. 这些重写后的输出是预期的:
no body
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.