代码之家  ›  专栏  ›  技术社区  ›  StoneThrow

Jenkins/Groovy:如何从共享库类构造函数中调用readJSON?

  •  0
  • StoneThrow  · 技术社区  · 3 年前

    如何在包含空JSON对象的Jenkins共享库中定义类?

    // src/org/build/Report.groovy
    
    package org.build
    
    public class Report implements Serializable {
      def steps
      def json
    
      Report(steps) {
        this.steps = steps
    
        this.json = emptyJson()
      }
    
      @NonCPS
      def emptyJson() {
        return this.steps.readJSON( text: '{}' )
      }
    }
    

    …从此管道实例化:

    @Library('my-library')
    import org.build.Report
    pipeline {
      agent any
      stages {
        stage("foo") {
          steps {
            script {
              rep = new org.build.Report(this)
            }
          }
        }
      }
    }
    

    …并失败,返回错误: expected to call org.build.Report.<init> but wound up catching readJSON; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/


    今天早些时候,我还以为我已经想好了如何解决这类问题。
    早些时候,我在从共享库类调用共享库函数时遇到了同样的错误。我根据错误消息所指出的链接上的指南解决了这个问题,即用注释共享库功能 @NonCPS .
    即在下面的代码中,class FirstClass 能够调用函数 firstNonNull() 因为函数是用注释的 @非CPS ; 在没有注释的情况下,此代码生成了与上述问题中相同的错误:

    // src/org/example/FirstClass.groovy
    
    package org.example
    
    public class FirstClass implements Serializable {
      def steps
      def var
    
      FirstClass(steps) {
        this.steps = steps
        this.var = steps.utils.firstNonNull( [null, null, "assigned_from_ctor"] )
      }
    }
    
    // vars/utils.groovy
    
    @NonCPS
    def firstNonNull( arr ) {
      for ( def i in arr ) { if ( i ) { return i } }
    
      return null
    }
    
    @Library('my-library')
    import org.example.FirstClass
    pipeline {
      agent any
      stages {
        stage("foo") {
          steps {
            script {
              first_class = new org.example.FirstClass(this)
            }
          }
        }
      }
    }
    

    为什么这种方法不适用于 Report 类调用 readJSON ?

    0 回复  |  直到 3 年前