Final-keyword doesn't work properly in Pipeline

I want to use a constant in my pipeline:

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                script {
                    final String str = "someVal"
                    str = "yetAnotherVal" // Exception expected
                    echo str
                }
            }
        }
    }
}

But this pipeline is executed successfully, I get output in stdout: “yetAnotherVal”

I went ahead and simply ran the following code in Main Pipeline Script via Replay:

final String str = "someVal"
str = "yetAnotherVal" // Exception expected
println str

The result is the same

Is this related to Jenkins using Groovy 2.4.21?

I assume so, because Groovy 2.4.21 also has this behavior:

ilyait@DESKTOP-H4GIJH3:/mnt/c/Users/ilya/Documents$ cat main.groovy
final String str = "someVal"
str = "1"
println str
ilyait@DESKTOP-H4GIJH3:/mnt/c/Users/ilya/Documents$ ./groovy-2.4.21/bin/groovy main.groovy
1

This is fixed in Groovy 2.5.10:

ilyait@DESKTOP-H4GIJH3:/mnt/c/Users/ilya/Documents$ ./groovy-2.5.10/bin/groovy main.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/mnt/c/Users/ilya/Documents/main.groovy: 2: The variable [str] is declared final but is reassigned
. At [2:1]  @ line 2, column 1.
   str = "1"
   ^

1 error

If this is indeed related to an outdated version of Groovy, what stage is this issue at now?


My Jenkins setup:

Jenkins: 2.492.2
OS: Linux - 5.15.167.4-microsoft-standard-WSL2
Java: 17.0.14 - Eclipse Adoptium (OpenJDK 64-Bit Server VM)
installed-plugins.log (2.9 KB)

Yes, you are most likely hitting this because Jenkins is using a version of Groovy that doesn’t work for final in the way you are expecting. Updating Groovy is a HUGE undertaking, that I am not sure is on the roadmap yet, but I could be wrong.

Thanks for the reply!)

Can the community help advance this complex task? If there are open issues I would be happy to see what I can do

https://issues.jenkins.io/browse/JENKINS-53372 is the first ticket for upgrading from 2.4 to 2.5
The biggest problem seems to be the sandboxing done in Jenkins

Updating Groovy would not likely fix this. Pipeline script is run through a Jenkins-specific transformer which winds up essentially running an independent interpreter, and I suppose nobody bothered to check for the final modifier in this context. Just pretend the modifier does not exist and do not assign another value.