简体   繁体   中英

Jenkins Shared Library Global/Singleton Class

I am looking for some guidance on the design of a Jenkins Shared Library, with respect to using a class, initializing it, and then being able to use that instance in any of my vars files.

Structure

src
  - foo
   - class
     - Configuration.groovy
vars
  - cicd.groovy
  - doMore.groovy

Class

The following is a class I would like to initialize once, but then use anywhere, without having to pass it into each vars function, or reinitialize every time.

package foo.class

public class Configuration {

    public String Foo

    public String Bar    

}

Vars

In my cicd.groovy vars file, I have something like this:

#!groovy
import foo.class.Configuration

def call () {

    return initCicd()
}

def initCicd() {
    configuration = new Configuration()
    configuration.Foo = 'FOO'
    return configuration
}

But, in other vars files like doMore.groovy , I would like to use the same configuration instance.

#!groovy
import foo.class.Configuration

def call () {

    println configuration.Foo
}

Is there a Singleton pattern that that works in Jenkins Shared Library, or a way to reference an instance across vars files or steps? If possible, please share an example.

Thanks!

You can simply use Groovy's @Singleton annotation for your Configuration class and use Configuration.instance wherever you want to access configuration settings. Consider following example:

.
├── src
│   └── foo
│       └── Configuration.groovy
└── vars
    ├── cicd.groovy
    └── doMore.groovy

src/foo/Configuration.groovy

package foo

@Singleton
class Configuration {
    public String foo = 'foo_123'
    public String bar = 'bar_456'
}

vars/cicd.groovy

#!groovy

import foo.Configuration

def call() {
    return initCicd()
}

def initCicd() {
    println Configuration.instance.foo
    return Configuration.instance
}

vars/doMore.groovy

#!groovy

import foo.Configuration

def call() {
    println Configuration.instance.bar
}

In the pipeline script I simply call:

cicd()
doMore()

And I get something like that in the console log:

Loading library default_jenkins_libs@master
Attempting to resolve master from remote references...
 > git --version # timeout=10
 > git ls-remote -h -t file:///var/jenkins_home/libraries # timeout=10
Found match: refs/heads/master revision 4fa988ccde542d77d19febd72f532ef996971a5d
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url file:///var/jenkins_home/libraries # timeout=10
Fetching without tags
Fetching upstream changes from file:///var/jenkins_home/libraries
 > git --version # timeout=10
 > git fetch --no-tags --progress file:///var/jenkins_home/libraries +refs/heads/*:refs/remotes/origin/*
Checking out Revision 4fa988ccde542d77d19febd72f532ef996971a5d (master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 4fa988ccde542d77d19febd72f532ef996971a5d
Commit message: "update"
 > git rev-list --no-walk 39890b4ca39bf32ebde8c7ad143b110bf16cf6b3 # timeout=10
[Pipeline] echo
foo_123
[Pipeline] echo
bar_456
[Pipeline] End of Pipeline
Finished: SUCCESS

The one downside of using singletons is that they can get modified anywhere and this change is populated to all callers.

I obtain a nullpointer exception using this solution at the moment of

"Configuration.instance" 

Which jenkins version or Groovy are you using? I think that @Singleton annotation is not working.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM