What is the effect on @NonCPS in a Jenkins pipeline script

I have a pipeline script in Jenkins.

I used to get this exception:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:
Scripts not permitted to use method groovy.json.JsonSlurperClassic
parseText java.lang.String

I looked the exception up and I found some indications that I should annotate the method where theexception occurs with @NonCPS. I did this, without really understanding what this does.

After that however, an Exception that I was throwing in that method was no longer caught by a try clause.

So what’s the idea behind @NonCPS? What are the effects of using it?

  • Jenkins continually builds on Windows slave even with no repository changes
  • Hudson/Jenkins PMD Configuration
  • SSH git commands with username and password
  • Ant/Maven: “javadoc: warning - Error fetching URL”
  • Jenkins - Git Client plugin constantly cloning bare repository
  • spring-core dependency version error with a Jenkins Plugin
  • Require a downstream job to use the same commit as its parent
  • Create jenkins JLNP slave programmatically
  • One Solution collect form web for “What is the effect on @NonCPS in a Jenkins pipeline script”

    The exception that you are seeing is due to script security and sandboxing. Basically by default when you run a pipeline script it runs in a sandbox which only allow usage of certain methods and classes. There are ways to whitelist operations, check the link above.

    Now, the @NonCPS annotation is useful when you have methods which uses objects which aren’t serializable. Normally all objects that you create in your pipeline script must e serializable (reason for this is that Jenkins must be able to serialize the state of the script so that it can be paused and stored on disk). Now, when you put @NonCPS on a method Jenkins will execute the entire method in one go without the ability to pause. Also, you’re not allowed to reference any pipeline steps or CPS transformed methods from within an @NonCPS annotated method. More information about this can be found here.

    As for the exception handling. Not 100% sure what you are experiensing, I’ve tried the following and it works as expected:

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

    and

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

    and finally:

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

    All prints “Caught” as expected.

    Git Baby is a git and github fan, let's start git clone.