Каков эффект @NonCPS в сценарии конвейера Jenkins

111

У меня есть сценарий конвейера в Jenkins.

Раньше я получал это исключение:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: скриптам не разрешено использовать метод groovy.json.JsonSlurperClassic parseText java.lang.String

Я просмотрел исключение и обнаружил некоторые признаки того, что мне следует аннотировать метод, в котором возникает исключение @NonCPS. Я сделал это, толком не понимая, что это делает.

Однако после этого исключение, которое я выбрасывал в этот метод, больше не перехватывается tryпредложением.

Так в чем же идея @NonCPS? Каковы эффекты от его использования?

Октавиан
источник
1
В официальном блоге jenkins есть статья, которая вводит эту аннотацию и может вам помочь. jenkins.io/blog/2017/02/01/pipeline-scalability-best-practice
袁文涛

Ответы:

142

Исключение, которое вы видите, связано с безопасностью сценария и изолированной программной средой. По сути, по умолчанию, когда вы запускаете сценарий конвейера, он запускается в песочнице, которая позволяет использовать только определенные методы и классы. Есть способы занести операции в белый список, проверьте ссылку выше.

@NonCPSАннотацию полезно , когда у вас есть методы , которые используют объекты , которые не являются сериализации. Обычно все объекты, которые вы создаете в сценарии конвейера, должны быть сериализуемыми (причина этого в том, что Дженкинс должен иметь возможность сериализовать состояние сценария, чтобы его можно было приостановить и сохранить на диске).

Когда вы добавляете @NonCPSметод, Дженкинс выполнит весь метод за один раз без возможности приостановки. Кроме того, вам не разрешено ссылаться на какие-либо шаги конвейера или преобразованные методы CPS из @NonCPSаннотированного метода. Более подробную информацию об этом можно найти здесь .

Что касается обработки исключений: не уверен на 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();

Все печатают «Поймано», как и ожидалось.

Джон С
источник
Когда я использую @NonCPS, Дженкинс не может найти этот метод, так как я получаю сообщение об ошибке вродеhudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method
Арун