Jaki jest efekt @NonCPS w skrypcie potoku Jenkinsa

110

Mam skrypt potoku w Jenkins.

Kiedyś otrzymywałem ten wyjątek:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: skrypty nie mogą używać metody groovy.json.JsonSlurperClassic parseText java.lang.String

Sprawdziłem wyjątek i znalazłem pewne wskazówki, że powinienem opisać metodę, w której występuje wyjątek @NonCPS. Zrobiłem to, nie rozumiejąc, co to robi.

Jednak po tym wyjątek, który rzucałem w tej metodzie, nie był już przechwytywany przez tryklauzulę.

Więc jaki jest pomysł @NonCPS? Jakie są efekty jej stosowania?

oktawski
źródło
1
Na oficjalnym blogu Jenkinsa znajduje się artykuł, który przedstawia tę adnotację i może Ci pomóc. jenkins.io/blog/2017/02/01/pipeline-scalability-best-practice
袁文涛

Odpowiedzi:

142

Wyjątek, który widzisz, wynika z bezpieczeństwa skryptów i piaskownicy. Zasadniczo, domyślnie, gdy uruchamiasz skrypt potoku, działa on w piaskownicy, która pozwala na użycie tylko niektórych metod i klas. Istnieją sposoby na umieszczenie operacji na białej liście, sprawdź powyższy link.

@NonCPSAdnotacja jest przydatna, gdy masz metody, które używają przedmiotów, które nie są do serializacji. Zwykle wszystkie obiekty, które tworzysz w skrypcie potoku, muszą być serializowane (powodem jest to, że Jenkins musi mieć możliwość serializacji stanu skryptu, aby można go było wstrzymać i przechowywać na dysku).

Kiedy wprowadzisz @NonCPSmetodę, Jenkins wykona całą metodę za jednym razem, bez możliwości wstrzymania. Ponadto nie możesz odwoływać się do żadnych kroków potoku ani metod przekształconych przez CPS z poziomu metody z @NonCPSadnotacjami. Więcej informacji na ten temat można znaleźć tutaj .

Jeśli chodzi o obsługę wyjątków: Nie jestem w 100% pewien, czego doświadczasz; Wypróbowałem następujące i działa zgodnie z oczekiwaniami:

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

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

i

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

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

mySecondFunction();

i w końcu:

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

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

mySecondFunction();

Wszystko drukuje „Złapany” zgodnie z oczekiwaniami.

Jon S.
źródło