• Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • pipeline
    • Jenkins ver. 1.606
      Workflow 1.5

      Consider the following script:

      node {  
          fn("This should only be one string")
      }
      
      def fn (String... strs) {
          echo "${strs.size()}"
      }
      

      This results in the following output:

      Running: Allocate node : Body : Start
      Running: Print Message
      30
      Running: Allocate node : Body : End
      Running: Allocate node : End
      Running: End of Workflow
      Finished: SUCCESS
      

      Under a groovy console the result is as we'd expect, there is one String in the array of Strings.

      def fn (String... strs) {
          println "${strs.size()}"
      }
      
      fn("This should only be one string")
      return
      

      Result:

      1
      

      I'm guessing this is just a bug?
      In the meantime is there a workaround? I'd like a function to handle an array of strings, and need to loop through the Strings, not individual characters.

          [JENKINS-27893] Varargs mishandled in Groovy CPS

          Jesse Glick added a comment -

          You may be the first to try to use varargs in a Groovy CPS-transformed script. Disambiguating varargs calls is complicated enough in Java, and argument handling is an order of magnitude more complicated in Groovy, so I am not that surprised it does not work. The following does work:

          fn(["This should only be one string"])
          def fn(strs) {
              echo "${strs.size()}"
          }
          

          Jesse Glick added a comment - You may be the first to try to use varargs in a Groovy CPS-transformed script. Disambiguating varargs calls is complicated enough in Java, and argument handling is an order of magnitude more complicated in Groovy, so I am not that surprised it does not work. The following does work: fn([ "This should only be one string" ]) def fn(strs) { echo "${strs.size()}" }

          Thomas Dalton added a comment -

          Thanks Jesse.

          For the benefit of others I've tried the following:

          node {  
              fn1("This should only be one string")
              fn1("Two", "Strings")
              fn2(["is", "This", "Three?"])
              fn3(["What", "about", "this?"] as String[])
              fn4(["Or", "perhaps", "this?"])
          }
          
          def fn1 (String... strs) {
              echo "${strs.size()}"
              def String s = ""
              for (int i = 0; i < strs.size(); i++) {
                  s += "${strs[i]} "
              }
              echo "$s"
          }
          
          def fn2 (strs) {
              echo "${strs.size()}"
              def String s = ""
              for (int i = 0; i < strs.size(); i++) {
                  s += "${strs[i]} "
              }
              echo "$s"
          }
          
          def fn3 (String[] strs) {
              echo "${strs.size()}"
              def String s = ""
              for (int i = 0; i < strs.size(); i++) {
                  s += "${strs[i]} "
              }
              echo "$s"
          }
          
          def fn4 (List strs) {
              echo "${strs.size()}"
              def String s = ""
              for (int i = 0; i < strs.size(); i++) {
                  s += "${strs[i]} "
              }
              echo "$s"
          }
          

          Here were the results:

          Running: Allocate node : Start
          Running on master in /nobackup/thdalton/jenkins/workspace/Sandbox
          Running: Allocate node : Body : Start
          Running: Print Message
          30
          Running: Print Message
          T h i s   s h o u l d   o n l y   b e   o n e   s t r i n g 
          Running: Print Message
          3
          Running: Print Message
          T w o 
          Running: Print Message
          3
          Running: Print Message
          is This Three? 
          Running: Print Message
          4
          Running: Print Message
          W h a t 
          Running: Print Message
          3
          Running: Print Message
          Or perhaps this? 
          Running: Allocate node : Body : End
          Running: Allocate node : End
          Running: End of Workflow
          Finished: SUCCESS
          

          I think I prefer the explicit List in fn4() so I shall go with that thanks.

          Thomas Dalton added a comment - Thanks Jesse. For the benefit of others I've tried the following: node { fn1( "This should only be one string" ) fn1( "Two" , "Strings" ) fn2([ "is" , "This" , "Three?" ]) fn3([ "What" , "about" , " this ?" ] as String []) fn4([ "Or" , "perhaps" , " this ?" ]) } def fn1 ( String ... strs) { echo "${strs.size()}" def String s = "" for ( int i = 0; i < strs.size(); i++) { s += "${strs[i]} " } echo "$s" } def fn2 (strs) { echo "${strs.size()}" def String s = "" for ( int i = 0; i < strs.size(); i++) { s += "${strs[i]} " } echo "$s" } def fn3 ( String [] strs) { echo "${strs.size()}" def String s = "" for ( int i = 0; i < strs.size(); i++) { s += "${strs[i]} " } echo "$s" } def fn4 (List strs) { echo "${strs.size()}" def String s = "" for ( int i = 0; i < strs.size(); i++) { s += "${strs[i]} " } echo "$s" } Here were the results: Running: Allocate node : Start Running on master in /nobackup/thdalton/jenkins/workspace/Sandbox Running: Allocate node : Body : Start Running: Print Message 30 Running: Print Message T h i s s h o u l d o n l y b e o n e s t r i n g Running: Print Message 3 Running: Print Message T w o Running: Print Message 3 Running: Print Message is This Three? Running: Print Message 4 Running: Print Message W h a t Running: Print Message 3 Running: Print Message Or perhaps this ? Running: Allocate node : Body : End Running: Allocate node : End Running: End of Workflow Finished: SUCCESS I think I prefer the explicit List in fn4() so I shall go with that thanks.

          As of 1.15, I couldn't reproduce this. groovy-cps had a varargs related fixes in JENKINS-32062, so presumably that had fixed it.

          I've added a test case to groovy-cps.

          Kohsuke Kawaguchi added a comment - As of 1.15, I couldn't reproduce this. groovy-cps had a varargs related fixes in JENKINS-32062 , so presumably that had fixed it. I've added a test case to groovy-cps.

            kohsuke Kohsuke Kawaguchi
            tomjdalton Thomas Dalton
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: