Search code examples
jenkinsgroovyjenkins-pipeline

In my Jenkins shared library, why am I seemingly not executing my methods?


I have the following shared-library structure

com/company/test/
                /ServiceBuilder.groovy
                /MonoBuilder.groovy
                /MicroServiceBuilder.groovy

Then in src/com/test/builders, I have these 3 files

#ServiceBuilder.groovy
package com.company.test

abstract class ServiceBuilder implements Serializable {
  protected String msg = null
  // Used by all sub-classes
  protected def printMsg() {
    println "${this.msg}"
  }
  // Implement in sub-classes
  protected def setMsg(final String msg) {
  }
}

#MicroserviceBuilder.groovy
package com.company.test

class MicroserviceBuilder extends ServiceBuilder {
  MicroserviceBuilder(){
    super()
  }
  def setMsg(final String msg) {
    println this.getClass()
    this.msg = "Mirco: $msg"
  }
}

#MonoServiceBuilder
package com.company.test

class MonoBuilder extends ServiceBuilder {
  MonoBuilder(){
    super()
  }
  def setMsg(final String msg) {
    println this.getClass()
    this.msg = "Mono: $msg"
  }
}

Here's is the Jenkinsfile cat use the above shared library

@Library("my-shared-lib@feature/test-shared-lib") _
import com.company.test.ServiceBuilder
import com.company.test.MonoBuilder
import com.company.test.MicroserviceBuilder

node("linux-ubuntu") {
  stage("Mono"){
    ServiceBuilder builder = new MonoBuilder()
    builder.setMsg("hello")
    builder.printMsg()
  }
  stage("Micro"){
    ServiceBuilder builder = new MicroserviceBuilder()
    builder.setMsg("hola")
    builder.printMsg()
  }
}

The code executes, but I don't see any of the expected println output. I expected

  • class type to be printed when I call object.setMsg(...)
  • Mono: hello for the MonoService.printMsg() call
  • Micro: hola for the Microservice.printMsg() call

But just see in the Jenkins console

Running on linux-ubuntu-1 in /home/jenkins/workspace/Utilities/Playground/test-shared-lib
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Mono)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Micro)
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline

What am I missing? TIA


Solution

  • I got it working by looking at Why do I love Jenkins shared libraries?. Here are my 3 modified Groovy files, where I added a jfile attribute, which is the this pointer of the calling Jenkinsfile.

    #ServiceBuilder.groovy
    package com.company.test
    
    abstract class ServiceBuilder implements Serializable {
      protected def jfile = null
      protected String msg = null
      protected def printMsg() {
        jfile.println "${this.getClass()}: ${this.msg}"
      }
      protected def setMsg(final String msg) {
      }
    }
    
    #MicroserviceBuilder.groovy
    package com.company.test
    
    class MicroserviceBuilder extends ServiceBuilder {
      MicroserviceBuilder(final def jfile){
        super()
        this.jfile = jfile
      }
      def setMsg(final String msg) {
        jfile.println this.getClass()
        this.msg = "Mirco: $msg"
      }
    }
    
    #MonoBuilder.groovy 
    package com.zift.test
    
    class MonoBuilder extends ServiceBuilder {
      MonoBuilder(final def jfile){
        super()
        this.jfile = jfile
      }
      def setMsg(final String msg) {
        jfile.println this.getClass()
        this.msg = "Mono: $msg"
      }
    }
    

    And here's the Jenkinsfile

    @Library("zift-infrastructure@feature/test-share-lib") _
    import com.company.test.ServiceBuilder
    import com.company.test.MonoBuilder
    import com.company.test.MicroserviceBuilder
    
    node("linux-ubuntu") {
      stage("Mono"){
        ServiceBuilder builder = new MonoBuilder(this)
        builder.setMsg("hello")
        builder.printMsg()
      }
      stage("Micro"){
        ServiceBuilder builder = new MicroserviceBuilder(this)
        builder.setMsg("hola")
        builder.printMsg()
      }
    }
    

    The Jenkins console output now shows

    Running on linux-ubuntu-2 in /home/jenkins/workspace/Utilities/Playground/test-shared-lib
    [Pipeline] {
    [Pipeline] stage
    [Pipeline] { (Mono)
    [Pipeline] echo
    class com.zift.test.MonoBuilder
    [Pipeline] echo
    class com.zift.test.MonoBuilder: Mono: hello
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] stage
    [Pipeline] { (Micro)
    [Pipeline] echo
    class com.zift.test.MicroserviceBuilder
    [Pipeline] echo
    class com.zift.test.MicroserviceBuilder: Mirco: hola
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }
    [Pipeline] // node
    [Pipeline] End of Pipeline
    

    which is the expected output. But why did I have to do this, using the caller's println instead of being able to do it in the classes themselves?