在 Jenkinsfile 中使用 Tuple 时无法批准 RejectedAccessException

Unapprovable RejectedAccessException when using Tuple in Jenkinsfile

我尝试在 Jenkinsfile 中使用 Tuple。

我写的那一行是def tupleTest = new Tuple('test', 'test2').

但是,Jenkins 不接受这一行,并继续将以下错误写入控制台输出:

No such constructor found: new groovy.lang.Tuple java.lang.String java.lang.String. Administrators can decide whether to approve or reject this signature.

...

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such constructor found: new groovy.lang.Tuple java.lang.Integer java.lang.String

...

当我访问 "Script Approval" 配置时,我看不到任何待批准的脚本。

遵循 this link, I tried to install and enable the "Permissive Security" 插件,但它也没有帮助 - 错误是一样的。

我什至尝试手动将有问题的签名添加到 scriptApproval.xml 文件中。添加后,在已批准的签名列表中可以看到,但错误依旧。

我做错了什么吗?

这或多或少是groovy.lang.Tuple构造函数+Jenkins沙盒Groovy模式造成的问题。如果你看一下这个 class 的构造函数,你会看到 something like this:

package groovy.lang;

import java.util.AbstractList;
import java.util.List;

public class Tuple extends AbstractList {
    private final Object[] contents;
    private int hashCode;

    public Tuple(Object[] contents) {
        if (contents == null) throw new NullPointerException();
        this.contents = contents;
    }

    //....
}

Groovy 沙箱模式 (所有 Jenkins 管道默认启用) 确保每次调用都通过脚本批准检查。它不是万无一失的,当它看到 new Tuple('a','b') 时,它认为用户正在寻找一个恰好匹配两个 String 类型参数的构造函数。并且因为这样的构造函数不存在,所以它抛出这个异常。但是,有两个简单的解决方法可以解决此问题。

改用groovy.lang.Tuple2

如果您的元组是一对,请改用 groovy.lang.Tuple2。关于这个 class 的好消息是它提供了一个构造函数 that supports two generic types,所以它适用于你的情况。

使用精确的Object[]构造函数

或者,您可以使用确切的构造函数,例如

def tuple = new Tuple(["test","test2"] as Object[])

这两个选项都需要脚本批准才能使用(但是,在这种情况下,两个构造函数都会出现在进程中脚本批准页面中)。

我在尝试在 jenkins 上使用元组时遇到了同样的问题,所以我发现我可以简单地使用列表文字来代替:

def tuple = ["test1", "test2"]

相当于

def (a, b) = ["test1", "test2"]

所以现在,我没有返回一个元组,而是在我的方法中返回一个列表

def myMethod(...) {
    ...
    return ["test 1", "test 2"]
}

...

def (a, b) = myMethod(...)