Shared Library and @Field - not global

I had to replace an groovy.transform.Field variable in the /vars script with a singleton in the /src directory. What I found is that OTHER scripts in /vars got their own instance. So, the log() script had a Level variable … INFO, DEBUG, TRACE, etc. and in the main Jenkinsfile/script would set the level to DEBUG, but scripts would have the initial value. Is this what - Internally, scripts in the vars directory are instantiated on-demand as singletons - means.

I’m sorry I don’t have any idea what your asking if anything. Its kinda just a statement.

I’ve only used shared libraries where var/ is functions (ex buildHelpChart()). I haven’t used src/ yet, but it looks like based on Extending with Shared Libraries things in src/ are classes you can import and use as classes.

What log() script are you talking about? What level? do you have your snippet public at all describing your problem?

thanks for that feedback. Let me re-phrase as a question. I have two scripts in /vars, and the main script/Jenkins file.

// vars/log.groovy:
@groovy.transform.Field
int logLevel = INFO // say that's 0

setLevel( int level ) { logLevel = level }

call( int level, String message ) {
  if (level <= logLevel) { echo "${message}" }
// vars/foo.groovy
call() { log( DEBUG, "hello world.") }
// Jenkinsfile
log.setLevel(DEBUG) // say debug is 1
foo()

Question: why does foo() never echo “hello world” ? When I call setLevel(DEBUG) in the Jenkinsfile, why is it still “INFO” within log() ?

A few things,

1 - @Field decorator makes a variable an instance field , which is automatically not “global” in static variable sense. Without @Field, the variable would be a script local, with it it is an instance field.

2 - Jenkins does weird thing with items in /vars - I think it lazy-loads them on demand for you and tries to reuse them, but it appears that Jenkinsfile vs code in vars a seem to get a different instance. I would not count on the instances being the same.

3 - To achieve what you are trying to achieve you need to either a - pass context, or b - use a true static. Not sure if scripts support statics - need to look it up, but you can simply create a new class (in /src, or as an inner class inside log.groovy and set a static variable to store log level.

1 Like