11

So I have the following bit of code (the important bits):

import java.lang.String;
//More imports ...

String errorString = ""
//More global variables

def mainMethod(){
    if (errorString.length()) {
        errorString += "BTW, fields with errors must be either corrected or set back to their original value before proceeding."
        invalidInputException = new InvalidInputException(errorString);
    }
}

Then when I run the script Jira throws back at me in catalina.out the following error message:

groovy.lang.MissingPropertyException: No such property: errorString for class: com.onresolve.jira.groovy.canned.workflow.validators.editAssigneeValidation

So I am unsure on why the script is not recognizing errorString as a variable or not.

Francisco
  • 2,050
  • 3
  • 14
  • 19

2 Answers2

18

Because you are using this code as an script. Upon compilation, all code not contained in methods will be put in the run() method, thus, your errorString will be declared in the run() method, and your mainMethod() will try to work with an errorString which doesn't exist neither in its own scope nor in the class' scope.

Some solutions:

1. @Field

Adding @Field turns your errorString into a field in the compiled script class

@groovy.transform.Field String errorString = ""

def mainMethod(){
    if (errorString.length()) {
        errorString += "BTW, fields with errors must be either corrected or set back to their original value before proceeding."
        invalidInputException = [error: errorString]
    }
}

mainMethod()

2. Binding

Remove the type declaration, so errorString will be contained in the script's binding:

errorString = ""

def mainMethod(){
    if (errorString.length()) {
        errorString += "BTW, fields with errors must be either corrected or set back to their original value before proceeding."
        invalidInputException = [error: errorString]
    }
}

mainMethod()

Here is groovyConsole output of your script:

ast

Will
  • 14,348
  • 1
  • 42
  • 44
  • So using the `@Field` descriptor. Do I have to do that for every variable that I define, or just for `String`? – Francisco Aug 31 '16 at 18:45
  • Only once to the script – Will Aug 31 '16 at 18:56
  • Ah so just throw it like so: `@Field \n var1 \n var2 \n etc...` ? – Francisco Aug 31 '16 at 19:11
  • I don't quite get the reasoning entirely I think. We already have a Script class instance a binding object. What's the downside of just binding those 'class' variables to the instance instead of putting them into the run method only when they have a type or 'def' attached to them? – stdout Feb 19 '18 at 13:44
  • 1
    Binding option did not work for me. @Field worked. Just to add, Jenkins documentation only mentions first option. may be that is the reason. https://jenkins.io/doc/book/pipeline/shared-libraries/#defining-global-variables – Manish Bansal Feb 21 '19 at 10:20
2

You have to add @Field annotation to errorString:

import java.lang.String
import groovy.transform.Field
//More imports ...

@Field
String errorString = ""
//More global variables

def mainMethod(){
    if (errorString.length()) {
        errorString += "BTW, fields with errors must be either corrected or set back to their original value before proceeding."
        invalidInputException = new     InvalidInputException(errorString);
    }
}
Gergely Toth
  • 6,638
  • 2
  • 38
  • 40