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

Implicit Groovy script args String[] is not recognized when scriptlet executes

      Trying to use the scriptlet as a regular Groovy script in support of plugins (such as Conditional step) that can only use a Groovy script and not a Scriptler script.

      Thought that I could use the scriptlet as a regualr Groovy script and pass it command line arguments instead of the scriptlet parameters. You need to make small modifications to your scriptlet to work with command line arguments AND parameters. Every Groovy script has an implicit args String[] that represents the command line arguments passed into the script.
      So if we had a hello.groovy scriptlet with one defined vName parameter. We would write a standard scriptlet as:

      name=vName
      println "Hello $name"
      

      We could adapt this as follows to work with one command line argument like this:
      >groovy hello.groovy John

      name=''
      if (args){
      name=args[0]
      }else{
      name=vName
      }
      println "Hello $name"
      

      When the code above is executed in a Jenkins Conditional Build setp as a Groovy script it works fine. But when you try to execute the script as a scriptlet, the implicit 'args' parameter is not recognized

      You get a 'MissingPropertyException: No such property: args for class: Script1' error

          [JENKINS-36830] Implicit Groovy script args String[] is not recognized when scriptlet executes

          I believe the args you are seeing, is injected by Groovy by default.

          From: http://groovy-lang.org/structure.html#_public_static_void_main_vs_script

          A script is always compiled into a class. The Groovy compiler will compile the class for you, with the body of the script copied into a run method.

          Then the class that Groovy generates wrapping your script is similar to:

          import org.codehaus.groovy.runtime.InvokerHelper
          class Main extends Script {                     
              def run() {                                 
                  println 'Groovy world!'                 
              }
              static void main(String[] args) {           
                  InvokerHelper.runScript(Main, args)     
              }
          }
          

          And [InvokeHelper](https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/InvokerHelper.java) does the rest. But Scriptler and some other plug-ins that support Groovy create a GroovyScript from scratch *and also specify the BindingContext*. So you won't have the default args provided by Groovy. You will only get what the developer that is evaluating the Groovy script added to the context.

          I don't know how it could be implemented in Scriptler, to allow a Groovy script to be evaluated in the same manner by Groovy and by Scriptler. Perhaps it would be easier to just add support to Scriptler to the conditional step plugin...

          Bruno P. Kinoshita added a comment - I believe the args you are seeing, is injected by Groovy by default. From: http://groovy-lang.org/structure.html#_public_static_void_main_vs_script A script is always compiled into a class. The Groovy compiler will compile the class for you, with the body of the script copied into a run method. Then the class that Groovy generates wrapping your script is similar to: import org.codehaus.groovy.runtime.InvokerHelper class Main extends Script { def run() { println 'Groovy world!' } static void main( String [] args) { InvokerHelper.runScript(Main, args) } } And [InvokeHelper] ( https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/InvokerHelper.java ) does the rest. But Scriptler and some other plug-ins that support Groovy create a GroovyScript from scratch * and also specify the BindingContext *. So you won't have the default args provided by Groovy. You will only get what the developer that is evaluating the Groovy script added to the context. I don't know how it could be implemented in Scriptler, to allow a Groovy script to be evaluated in the same manner by Groovy and by Scriptler. Perhaps it would be easier to just add support to Scriptler to the conditional step plugin...

          Thanks for the great explanation kinow. I agree that it would be great if Scriptler just supported the Conditional step plugin. It would unify the way we use Scriptler.

          Ioannis Moutsatsos added a comment - Thanks for the great explanation kinow . I agree that it would be great if Scriptler just supported the Conditional step plugin. It would unify the way we use Scriptler.

            domi Dominik Bartholdi
            ioannis Ioannis Moutsatsos
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: