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

Boolean parameter + environment = breaks pipeline (ClassCastException)

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Environment:
    • Similar Issues:

      Description

      If a pipeline contains any boolean parameters, AND the pipeline defines any environment variables, then the build fails with a cast exception between boolean and string.  The boolean parameters can either be defined in the pipeline script (my Jenkinsfiles had it this way when I encountered the problem), or they can be defined  Here's a simple pipeline script that demonstrates the problem and the console output...

      Create a new Pipeline job:

      • This proejct is parameterized:  add a Boolean Parameter with name "TestBooleanParameter", Description "test"
      • Definition:  Pipeline script
      • Script:
      • pipeline {
          agent any

          environment {
            ProjectFile = 'build.proj'
          }

          stages {
            stage("Prepare") {
              steps {
                script {
                  echo 'Hello world.'
                }
              }
            }
          }
        }

      Console output:

      [Pipeline] node
      Running on master in C:\bin\Jenkins\workspace\test-boolean-param
      [Pipeline] {
      [Pipeline] withEnv
      [Pipeline] {
      [Pipeline] }
      [Pipeline] // withEnv
      [Pipeline] }
      [Pipeline] // node
      [Pipeline] End of Pipeline
      java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String
      at hudson.EnvVars.put(EnvVars.java:74)
      at java.util.AbstractMap.putAll(Unknown Source)
      at java.util.TreeMap.putAll(Unknown Source)
      at hudson.EnvVars.<init>(EnvVars.java:93)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
      at java.lang.reflect.Constructor.newInstance(Unknown Source)
      at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
      at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:77)
      at org.codehaus.groovy.runtime.callsite.ConstructorSite.callConstructor(ConstructorSite.java:45)
      at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:247)
      at org.jenkinsci.plugins.pipeline.modeldefinition.model.Environment.getCredsMap(Environment.groovy:63)
      at org.jenkinsci.plugins.pipeline.modeldefinition.model.Environment$getCredsMap$3.call(Unknown Source)
      at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
      at org.jenkinsci.plugins.pipeline.modeldefinition.Utils.getEnvCredentials(Utils.groovy:334)
      at org.jenkinsci.plugins.pipeline.modeldefinition.Utils$getEnvCredentials$13.call(Unknown Source)
      at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
      at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:18)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withCredentialsBlock(jar:file:/C:/bin/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:243)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.call(jar:file:/C:/bin/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:78)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.inWrappers(jar:file:/C:/bin/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:380)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.inWrappers(jar:file:/C:/bin/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:379)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.call(jar:file:/C:/bin/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:77)
      at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(jar:file:/C:/bin/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy:221)
      at __cps.transform__(Native Method)
      at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
      at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
      at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
      at sun.reflect.GeneratedMethodAccessor163.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      at java.lang.reflect.Method.invoke(Unknown Source)
      at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
      at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:76)
      at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
      at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
      at sun.reflect.GeneratedMethodAccessor167.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      at java.lang.reflect.Method.invoke(Unknown Source)
      at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
      at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
      at com.cloudbees.groovy.cps.Next.step(Next.java:74)
      at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
      at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
      at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
      at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
      at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
      at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
      at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:165)
      at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:328)
      at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:80)
      at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:240)
      at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:228)
      at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
      at java.util.concurrent.FutureTask.run(Unknown Source)
      at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
      at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
      at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
      at java.util.concurrent.FutureTask.run(Unknown Source)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
      at java.lang.Thread.run(Unknown Source)
      Finished: FAILURE

       

      This problem started this past weekend.  I had installed updates for plugins (and Jenkins itself) a day or two prior.  After narrowing it down to a simple pipeline script that could demonstrate the problem, I did a fresh install of Jenkins on a new VM today and confirmed it happens there as well.

      My original pipeline script on my production Jenkins server is a multibranch project with a Jenkinsfile.  One thing that might be worth noting is that if, after a build failed due to this problem, if I edited the Jenkinsfile and removed all booelan parameters defined in it, then committed that and triggered the build, the next build would still fail–it seems the existence of the boolean parameters in the config.xml (based on the previous build) combined with having environment variables causes this error.  The next build after that would be fine (the parameters no longer exist in the xml).

      I found a workaround (hence why I chose 'minor' for the priority):  changing the parameters to be choices instead of boolean seems to work (although it looks like I'll need to either build twice to get rid of the old boolean parameter or go manually edit the xml files to clear them out).

        Attachments

          Issue Links

            Activity

            Hide
            oleg_nenashev Oleg Nenashev added a comment -

            Nothing to do in the Jenkins core

            Show
            oleg_nenashev Oleg Nenashev added a comment - Nothing to do in the Jenkins core
            Hide
            bendemtp Benjamin Raimondi added a comment -

            I don't think that is a "minor" bug.

            It can be reproduce with :

            pipeline {
              agent any
              environment {
                ProjectFile = 'build.proj'
              }
              parameters {
                booleanParam(name: 'BOOLEAN_PARAM', defaultValue: false, description: '')
              }
              stages {
                stage("Prepare") {
                  steps {
                    script {
                      echo 'Hello world.'
                    }
                  }
                }
              }
            }
            

            In this case there is no workaround because, regarding pipeline documentation, there is no parameter of type "choices".

            Show
            bendemtp Benjamin Raimondi added a comment - I don't think that is a "minor" bug. It can be reproduce with : pipeline {   agent any   environment {     ProjectFile = 'build.proj'   } parameters { booleanParam(name: 'BOOLEAN_PARAM' , defaultValue: false , description: '') }   stages {     stage( "Prepare" ) {       steps {         script {           echo 'Hello world.'         }       }     }   } } In this case there is no workaround because, regarding pipeline documentation , there is no parameter of type "choices".
            Hide
            abayer Andrew Bayer added a comment -
            Show
            abayer Andrew Bayer added a comment - PR up at https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/151  - sorry about that!
            Hide
            dotnetsparky Shaun Sutterfield added a comment - - edited

            Benjamin Raimondi, the workaround I mentioned (while we're waiting for Andrew's PR to get approved)...  

            The documentation is incomplete (the link you reference has a note at the end of the section... "A comprehensive list of available parameters is pending the completion of INFRA-1503").  I got a choice parameter to work like this:

             

            parameters {
             choice(name: 'SampleParam', choices: 'false\ntrue', description: 'This is a sample parameter.')
             }

             

            Unfortunatelly, the constructor that allows setting a default value is private, so you can't do that, but it will instead use the first choice as the default (so use 'true\nfalse' if you want the default to be true).

            Show
            dotnetsparky Shaun Sutterfield added a comment - - edited Benjamin Raimondi , the workaround I mentioned (while we're waiting for Andrew's PR to get approved)...   The documentation is incomplete (the link you reference has a note at the end of the section... "A comprehensive list of available parameters is pending the completion of INFRA-1503 ").  I got a choice parameter to work like this:   parameters { choice(name: 'SampleParam' , choices: ' false \ntrue' , description: 'This is a sample parameter.' ) }   Unfortunatelly, the constructor that allows setting a default value is private, so you can't do that, but it will instead use the first choice as the default (so use 'true\nfalse' if you want the default to be true).
            Hide
            scm_issue_link SCM/JIRA link daemon added a comment -

            Code changed in jenkins
            User: Andrew Bayer
            Path:
            pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/Environment.groovy
            pipeline-model-definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/EnvironmentTest.java
            pipeline-model-definition/src/test/resources/booleanParamAndEnv.groovy
            http://jenkins-ci.org/commit/pipeline-model-definition-plugin/153edcff44d63d14933db2de5d0fc04131a43cfc
            Log:
            [FIXED JENKINS-43486] Handle non-String parameters in env resolution

            Show
            scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Andrew Bayer Path: pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/Environment.groovy pipeline-model-definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/EnvironmentTest.java pipeline-model-definition/src/test/resources/booleanParamAndEnv.groovy http://jenkins-ci.org/commit/pipeline-model-definition-plugin/153edcff44d63d14933db2de5d0fc04131a43cfc Log: [FIXED JENKINS-43486] Handle non-String parameters in env resolution
            Hide
            abayer Andrew Bayer added a comment -

            Will be in the 1.1.3 release.

            Show
            abayer Andrew Bayer added a comment - Will be in the 1.1.3 release.

              People

              • Assignee:
                abayer Andrew Bayer
                Reporter:
                dotnetsparky Shaun Sutterfield
              • Votes:
                2 Vote for this issue
                Watchers:
                9 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: