因为我们有几个具有相似逻辑且需要某些公共属性的管道,所以我们创建了一个goovy文件并将一些公共方法属性放入其中。 但是我们发现无法访问groovy文件中定义的属性。
这是我们的groovy文件:common.groovy:
def MyProp="value"
def myMethod() {
//Fail here
println MyProp
}
return this
JenkinsFile:
node('test') {
checkout scm
def jenkinsCommon = load "common.groovy"
jenkinsCommon.myMethod()
// Below also fail
println jenkinsCommon.MyProp
}
使用此Jenkinsfile运行作业时,出现以下异常:
groovy.lang.MissingPropertyException: No such property: MyProp for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:242)
at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:288)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
at Script1.myMethod(Script1.groovy:4)
at WorkflowScript.run(WorkflowScript:33)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
at sun.reflect.GeneratedMethodAccessor286.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
如何在管道加载的Groovy文件中定义和使用该属性?
答案 0 :(得分:0)
如果要使用在方法外部定义的变量,则必须使用@Field
注释对其进行注释,例如
import groovy.transform.Field
@Field
def myProp="value"
def myMethod() {
println myProp
}
每个Groovy脚本都被编译为扩展groovy.lang.Script
类的类,并且脚本中定义的每个方法均被编译为类级方法,而其余脚本主体则在Script.run()
方法中执行。
这意味着当您的myMethod
尝试访问myProp
时,它会失败,因为myProp
被编译为Script.run()
方法中可用的局部变量。 @Field
注释将给定变量提升为类级别的变量,因此可以从脚本中定义的任何方法进行访问。
答案 1 :(得分:0)
只需将def MyProp="value"
更改为env.MyProp="value"
即可!