learner
learner

Reputation: 505

exception while executing groovy script from jenkinsfile groovy.lang.MissingPropertyException: No such property: args for class: groovy.lang.Binding

I am trying to execute "myGroovyScript.groovy" from a jenkinsfile which is running at a remote server. Groovy script is kept in a path in server (not checked in scm). But I am getting exception. Is there a better way to do if I checkin the groovy script in github in same repo where jenkinsfile is also there.

I have a jenkinsfile as below

node('abcd'){

        def buildInput;

      echo 'Deploying build'
     if(!params.buildName) {
         buildInput = input(
                          id: 'userInput', message: 'What is the build name?', parameters: [
                          [$class: 'TextParameterDefinition', defaultValue: 'BuildNameIsABC', description: 'Environment', name: 'buildName']
                          ])
      }
      buildToUse = params.buildName ? params.buildName : buildInput;
      echo ("Env: "+buildToUse);

      if ( "${params.buildParam}" == 'prequal' || !params.buildParam ){

        stage('Prequal') {
                echo 'Checking prequal status for my product build'
            def rootDir = '/home/pathToGroovyScript'
            def example = load "${rootDir}myGroovyScript.groovy"
}

I am trying to execute "myGroovyScript.groovy" from above jenkinsfile. Groovy script is as below

#!/usr/bin/env groovy
def maxAttempt = 90
def attempt = 1
def frontDoorUrl
def waitTimeMS = 10000
def uiNodes
def service = args[0]
def uiNodesReady = false
def uiFrontDoorReady = false


//init important data in regards to the service
if ("abcd".equalsIgnoreCase(service)) {
    println 'Init config for service abcd'
    frontDoorUrl = "http://myFrontDoorURL"
    uiNodes = ["http://myUINodes"]
}

//ping nodes <service>
while (attempt <= maxAttempt && uiNodesReady == false) {
    println 'Attempt #' + attempt
    for (i = 0; i < uiNodes.size(); i++) {
        def result = ('curl -m 2 --write-out "%{http_code}" ' + uiNodes[i]).execute().text
        println 'UI node: ' + i + ' ::: ' + uiNodes[i] + ' status: ' + result
        if (result.contains("<StatusCode>200</StatusCode>")) {
            uiNodesReady = true
        } else {
            uiNodesReady = false
            break
        }
    }
}

I am running my jenkinsfile in remote linux server and after running it gives below stack trace. could you please help whats the problem. Sorry for long post.

groovy.lang.MissingPropertyException: No such property: args for class: groovy.lang.Binding
    at groovy.lang.Binding.getVariable(Binding.java:63)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:224)
    at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28)
    at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
    at Script1.run(Script1.groovy:8)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
    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.GeneratedMethodAccessor513.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    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:83)
    at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:173)
    at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:162)
    at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)

Upvotes: 4

Views: 14799

Answers (1)

Vitalii Vitrenko
Vitalii Vitrenko

Reputation: 10405

The problem is that in myGroovyScript.groovy you use def service = args[0] but args variable is not defined anywhere. You can define it as a global variable in Jenkinsfile this way

//...
args = ['abcd'] //note you have to define it without def to make it global
def example = load "${rootDir}myGroovyScript.groovy" 
//...

But using global variables is error prone and not recommended. The better way would be wrapping myGroovyScript.groovy into function and then call it and pass service as parameter. Something like this
myGroovyScript.groovy:

#!/usr/bin/env groovy

def execute(service) {
    def maxAttempt = 90
    def attempt = 1
    def frontDoorUrl
    def waitTimeMS = 10000
    def uiNodes
    def uiNodesReady = false
    def uiFrontDoorReady = false

    // all code go into function and ramain the same
}
return this // you also need to return a reference to this script

And then in Jenkinsfile

def example = load "${rootDir}myGroovyScript.groovy"
example.execute('abc')

Upvotes: 4

Related Questions