@NonCPS在Jenkins流水线脚本中的作用是什么?

144

我在Jenkins中有一个流水线脚本。

以前我遇到过这个异常:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.json.JsonSlurperClassic parseText java.lang.String

我查了一下这个异常,发现应该用@NonCPS为出现异常的方法进行注解。虽然不是很理解,但我还是这样做了。

这之后,我发现这个方法抛出的异常不再被try语句捕捉到了。

那么,@NonCPS背后的思想是什么?使用它的影响是什么?


3
Jenkins官方博客有一篇介绍此注释并可能对您有所帮助的文章。https://jenkins.io/blog/2017/02/01/pipeline-scalability-best-practice/ - 袁文涛
1个回答

183
您看到的异常是由于脚本安全性和沙箱机制引起的。基本上,当您运行管道脚本时,默认情况下它会在一个仅允许使用某些方法和类的沙箱中运行。有一些方法可以将操作列入白名单,请查看上面的链接。 @NonCPS注释在使用不可序列化对象的方法时非常有用。通常,在管道脚本中创建的所有对象都必须是可序列化的(原因是Jenkins必须能够序列化脚本的状态,以便可以暂停并存储在磁盘上)。
当您在一个方法上放置@NonCPS时,Jenkins将一次性执行整个方法,而无法暂停。此外,您不允许从@NonCPS注释的方法中引用任何管道步骤或CPS转换方法。 这里可以找到更多信息
至于异常处理:我不确定您正在经历什么;我已尝试以下操作,并且按预期工作:
@NonCPS
def myFunction() {
    throw new RuntimeException();
}

try {
    myFunction();
} catch (Exception e) {
    echo "Caught";
}

并且

@NonCPS
def myFunction() {
    throw new RuntimeException();
}

def mySecondFunction() {
    try {
        myFunction();
    } catch (Exception e) {
        echo "Caught";
    }
}

mySecondFunction();

最后:

@NonCPS
def myFunction() {
    throw new RuntimeException();
}

@NonCPS
def mySecondFunction() {
    try {
        myFunction();
    } catch (Exception e) {
        echo "Caught";
    }
}

mySecondFunction();

所有的输出都符合预期,打印出 "Caught"。

2
当我使用@NonCPS时,Jenkins找不到该方法,因为我会收到类似于“hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method”的错误。 - Arun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接