Jenkins 管道脚本中@NonCPS 的作用是什么

我在詹金斯有一个管道脚本。

我曾经有过这样的例外:

异常: 不允许使用 groovy.json.JsonSlurperClassic 方法的脚本 Lang. String

我查找了这个异常,发现了一些迹象表明我应该对 @NonCPS中发生异常的方法进行注释。我做了这个,没有真正理解它的作用。

然而,在此之后,我在该方法中引发的 Exception 不再被 try子句捕获。

那么 @NonCPS背后的想法是什么? 使用它的效果是什么?

99315 次浏览

您看到的异常是由于 脚本安全和沙箱引起的。基本上,默认情况下,当您运行管道脚本时,它运行在一个沙箱中,该沙箱只允许使用某些方法和类。白名单操作有多种方法,请查看上面的链接。

当您有使用不可序列化对象的方法时,@NonCPS注释非常有用。通常,您在管道脚本中创建的所有对象都必须是可序列化的(原因是 Jenkins 必须能够序列化脚本的状态,以便它能够暂停并存储在磁盘上)。

当您将 @NonCPS放在一个方法上时,Jenkins 将一次执行整个方法,而无需暂停。此外,不允许从 @NonCPS注释方法内引用任何流水线步骤或 CPS 转换的方法。更多相关信息可以在这里找到.

至于异常处理: 不是100% 确定您正在经历什么; 我已经尝试了以下方法,它的工作原理与预期一样:

@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();

按照预期打印“捕获”。