100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Groovy and Jenkins Pipelines

Understand how Jenkins Pipeline uses Groovy for both Declarative and Scripted syntax, including shared libraries and CPS constraints.

Practical GroovyIntermediate10 min readJul 10, 2026
Analogies

Groovy as the Engine Behind Jenkinsfiles

Jenkins Pipeline, whether written as a Jenkinsfile using Declarative or Scripted syntax, is fundamentally a Groovy program executed inside the Jenkins Groovy CPS (Continuation-Passing Style) interpreter; Jenkins parses the file, compiles it as Groovy, and runs it step by step so that pipeline state can be serialized to disk, letting a build survive a Jenkins controller restart mid-pipeline.

🏏

Cricket analogy: Much like DRS (Decision Review System) can pause live play and later resume exactly from that ball once the third umpire rules, Jenkins Pipeline's Groovy CPS engine can pause a running build mid-step and resume it later without losing state.

Declarative vs Scripted Pipelines

Declarative pipelines wrap Groovy in a constrained pipeline { agent { } stages { stage('Build') { steps { } } } } structure that limits what you can write directly, favoring readability and validation, whereas Scripted pipelines drop you into raw Groovy inside a node { } block where you can use loops, try/catch, and arbitrary Groovy methods without the Declarative directive restrictions.

🏏

Cricket analogy: Much like T20 cricket imposes strict overs-per-bowler rules to keep the format standardized, Declarative Pipeline imposes a constrained pipeline { stages { } } structure, while Scripted Pipeline is closer to an unlimited-overs format where any Groovy logic is allowed.

Shared Libraries and Reusable Groovy Logic

Shared Libraries let teams package reusable Groovy code — global functions in vars/*.groovy and classes in src/ — that any Jenkinsfile across the organization can import with @Library('my-shared-lib') _ at the top of the file, turning common patterns like Slack notifications or Docker build steps into a single callable step such as notifySlack(status: 'SUCCESS').

🏏

Cricket analogy: Much like a national cricket board issues a standard coaching manual every franchise's academy must follow, a Jenkins Shared Library issues standard Groovy functions like notifySlack() that every team's Jenkinsfile can import via @Library.

groovy
// Jenkinsfile
@Library('my-shared-lib') _

pipeline {
    agent any
    environment {
        APP_VERSION = "1.2.${env.BUILD_NUMBER}"
    }
    stages {
        stage('Build') {
            steps {
                sh './gradlew build'
            }
        }
        stage('Test') {
            steps {
                sh './gradlew test'
            }
        }
        stage('Notify') {
            steps {
                notifySlack(status: 'SUCCESS', version: env.APP_VERSION)
            }
        }
    }
    post {
        failure {
            notifySlack(status: 'FAILURE', version: env.APP_VERSION)
        }
    }
}

Groovy CPS Transformation and Its Limits

Because Jenkins must be able to pause and resume a pipeline at any step (for example while waiting on an input step or an agent to become available), it transforms your Groovy code using CPS, which rewrites method calls into continuations; this means certain standard Groovy idioms — like using .collect { } inside heavily nested closures, or calling non-whitelisted Java library methods, or using try/catch around CPS-transformed calls incorrectly — can throw NotSerializableException or CPS-related errors unless you wrap them in @NonCPS or restructure the code.

🏏

Cricket analogy: Much like DRS reviews are restricted to specific dismissal types and can't be invoked for every decision, CPS transformation restricts which Groovy constructs (like certain non-whitelisted Java calls) can run safely inside a serializable pipeline step.

Declarative Pipeline still allows dropping into raw Groovy via a script { } block inside any steps { } section, giving you an escape hatch for loops or conditionals without abandoning the Declarative structure entirely.

Avoid non-serializable objects (like a raw java.io.File or an open database connection) as pipeline-level variables in Scripted Pipelines — CPS needs to serialize the pipeline's state to disk at every step, and non-serializable fields cause the build to fail with a NotSerializableException.

  • Jenkinsfiles are Groovy programs executed by Jenkins' CPS (Continuation-Passing Style) interpreter, which lets pipelines pause and resume.
  • Declarative Pipeline enforces a pipeline { stages { steps { } } } structure for validation and readability.
  • Scripted Pipeline gives raw Groovy inside node { }, allowing arbitrary loops, conditionals, and method calls.
  • Shared Libraries package reusable Groovy functions (vars/) and classes (src/) importable via @Library('name') _.
  • CPS transformation restricts certain Groovy idioms; use @NonCPS for code that can't be safely serialized.
  • A script { } block inside Declarative Pipeline lets you drop into raw Groovy when directives aren't enough.
  • Non-serializable objects stored as pipeline variables cause NotSerializableException under CPS.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#GroovyStudyNotes#GroovyAndJenkinsPipelines#Groovy#Jenkins#Pipelines#Engine#DevOps#StudyNotes#SkillVeris