web-dev-qa-db-ja.com

Jenkinsパイプラインスクリプトにおける@NonCPSの効果は何ですか

Jenkinsにパイプラインスクリプトがあります。

私はこの例外を取得していました:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:スクリプトはメソッドgroovy.json.JsonSlurperClassicのparseText Java.lang.Stringの使用を許可されていません

例外を調べたところ、例外が発生したメソッドに@NonCPSをアノテーションする必要があることを示す兆候がいくつか見つかりました。これが何をするのかを本当に理解することなく、私はこれをしました。

しかしその後、そのメソッドでスローしていたExceptionがtry句でキャッチされなくなりました。

@NonCPSの背後にある考え方は何ですか?それを使うことの効果は何ですか?

76
octavian

あなたが見ている例外は スクリプトセキュリティ とサンドボックス化によるものです。基本的に、デフォルトでは、パイプラインスクリプトを実行すると、サンドボックス内で実行され、特定のメソッドとクラスの使用しか許可されません。操作をホワイトリストに追加する方法があります。上記のリンクを確認してください。

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

すべての印刷物は期待どおりに「キャッチ」されました。

92
Jon S