Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-39122

Certain Groovy expressions cause Global Library loading to Silently Fail

      Summary

      Certain legitimate groovy expressions, when present in a groovy global shared library will cause any pipeline job that attempts to load the library to hang at the point immediately after the library is loaded. This occurs with no errors in the job console nor any errors in the jenkins logs, effectively leaving the user to have to start guessing at possible causes.

      Steps to Reproduce

      I don't know if there are other scenarios that will cause this but here is a reproducible one that I have come up with.

      Step 1

      Create a repo in git and configure it to be loaded on demand. In our case we are loading under the name 'pipeline-utils'.

      Step 2

      Create the following file in that library:

      /src/examples/Bug.groovy

      with conntent:

      package examples
      import groovy.transform.Field
      
      // This is the line that seems to be the real cause of the problem.  A final static field that invokes a function to get its value.
      @Field def static final API_BASE_URL = absolutizeUrl("api")
      
      def static absolutizeUrl(relativeUrl) { return "http://myserver/${relativeUrl}" }
      
      

      Step 3

      Now create a pipeline job with the following DSL:

      @Library('pipeline-utils')
      import examples.Bug
      
      //Though the bug seems to be triggered by the field declaration, it isn't activated if we don't invoke a function from the class in question.
      println Bug.absolutizeUrl('ui')
      

      Step 4

      Run this job and you will get output similar to the following:

      Started by user Baltrinic, Kenneth
      Loading library pipeline-utils@master
       > git rev-parse --is-inside-work-tree # timeout=10
      Fetching changes from the remote Git repository
       > git config remote.origin.url ssh://git@stash:7999/jenkins/pipeline-utils.git # timeout=10
      Fetching upstream changes from ssh://git@stash:7999/jenkins/pipeline-utils.git
       > git --version # timeout=10
       > git fetch --tags --progress ssh://git@stash:7999/jenkins/pipeline-utils.git +refs/heads/*:refs/remotes/origin/*
       > git rev-parse origin/master^{commit} # timeout=10
      Checking out Revision 164a989ac7555e33541894d966075819c3e66143 (origin/master)
       > git config core.sparsecheckout # timeout=10
       > git checkout -f 164a989ac7555e33541894d966075819c3e66143
       > git rev-list 395d5408a41619030e2855f01bb55a7103ce6b10 # timeout=10

      At this point there will be no further console output and the job is hung and must be forcibly aborted.

      Recommendations

      This is admittedly an esoteric scenario. I am not so concerned that a fix be implemented to allow this code to load correctly. My main concern is that the failure must not be silent. It may be impossible to account for all the ways in which things might fail to load or be processed by the CPS system, etc. But better error reporting that clearly identifies the offending file and line number should be possible. This took me the better part of five hours to run down given the dearth of info I had to go on and the size of the code base I was dealing with.

          [JENKINS-39122] Certain Groovy expressions cause Global Library loading to Silently Fail

          Sam Barron added a comment -

          I am having a similar issue

          Jenkins ver 2.16
          Pipeline: Shared Groovy Libraries 2.3

          I can't confirm what line from my groovy class is causing any issue.

          When I start a pipeline that loads shared libraries, I get the same hanging issue right after checking out the library, the pipeline doesn't start, and I have to manually abort and forcibly terminate the job.

          kbaltrinic How did you troubleshoot this?

          I didn't have any issues with the shared groovy libraries until I tried using two different versions (one 'master', one 'dev') during some testing.

          I'm going to try to upgrade the plugin and see if it helps. Looks like there was some work done on how different libraries are checked out.

          Sam Barron added a comment - I am having a similar issue Jenkins ver 2.16 Pipeline: Shared Groovy Libraries 2.3 I can't confirm what line from my groovy class is causing any issue. When I start a pipeline that loads shared libraries, I get the same hanging issue right after checking out the library, the pipeline doesn't start, and I have to manually abort and forcibly terminate the job. kbaltrinic How did you troubleshoot this? I didn't have any issues with the shared groovy libraries until I tried using two different versions (one 'master', one 'dev') during some testing. I'm going to try to upgrade the plugin and see if it helps. Looks like there was some work done on how different libraries are checked out.

          Sam Barron added a comment -

          Please disregard my comment. I discovered the issue was jenkins hanging for a failing assert https://issues.jenkins-ci.org/browse/JENKINS-34488

          I was doing asserts as the first step in my Pipeline.

          Sam Barron added a comment - Please disregard my comment. I discovered the issue was jenkins hanging for a failing assert https://issues.jenkins-ci.org/browse/JENKINS-34488 I was doing asserts as the first step in my Pipeline.

          Reinhold Füreder added a comment - - edited

          I also stumbled over a silent failure in a shared library:

          • The failure itself was a wrong ("com.acme.Util" instead of "com.acme.Constants") and thus missing class import (and clearly my own fault)
          • However, like kbaltrinic wrote: My main concern is that the failure must not be silent
            • Only when adding some "debug logs" via "echo" step the problem was logged – and only in Blue Ocean Pipeline view!
              No such property: Constants for class: ...
              

            • But still not in the classic UI:
            • And before the debug logs it just silently failed! This is the snippet with debug logs:
              import com.acme.Util // Bug => Should be com.acme.Constants
                    ...
                    post {
                      failure {
                        theScript.echo "failure..."
                        script {
                          theScript.echo "script..."
                          if (notifyDevopsInCaseOfFailure) {
                            theScript.echo "notify to emails: ${Constants.DEVOPS_EMAIL}"
                          ...
              

          Reinhold Füreder added a comment - - edited I also stumbled over a silent failure in a shared library: The failure itself was a wrong ("com.acme.Util" instead of "com.acme.Constants") and thus missing class import (and clearly my own fault) However, like kbaltrinic wrote: My main concern is that the failure must not be silent Only when adding some "debug logs" via "echo" step the problem was logged – and only in Blue Ocean Pipeline view! No such property: Constants for class: ... But still not in the classic UI: And before the debug logs it just silently failed! This is the snippet with debug logs: import com.acme.Util // Bug => Should be com.acme.Constants ... post { failure { theScript.echo "failure..." script { theScript.echo "script..." if (notifyDevopsInCaseOfFailure) { theScript.echo "notify to emails: ${Constants.DEVOPS_EMAIL}" ...

            Unassigned Unassigned
            kbaltrinic Kenneth Baltrinic
            Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: