Jenkins脚本化的管道:在这种特定情况下如何应用@NonCPS注释

问题描述 投票:2回答:1

我正在编写脚本化的Jenkins-Pipeline,该脚本需要将具有特定编码的String写入文件,如以下示例所示:

class Logger implements Closeable {

    private final PrintWriter writer

    [...]

    Logger() {
        FileWriter fw = new FileWriter(file, true)
        BufferedWriter bw = new BufferedWriter(fw)
        this.writer = new PrintWriter(bw)
    }

    def log(String msg) {
        try {
            writer.println(msg)
            [...]
        } catch (e) {
            [...]
        }
    }
}

上面的代码不起作用,因为PrintWriter不能序列化,所以我知道我必须防止某些代码进行CPS转换。但是,我不知道如何执行此操作,因为据我所知,@NonCPS批注只能应用于方法。我知道一种解决方案是将所有与输出相关的代码移至log(msg)并对该方法进行注释,但是这样,每次调用该方法时,我都必须创建一个新的编写器。

有人对我如何解决代码有想法吗?

提前感谢!

jenkins groovy jenkins-pipeline nio pipeline
1个回答
0
投票

这里是使用log的共享库中定义的vars\log.groovy函数使此工作有效的方法:

import java.io.FileWriter
import java.io.BufferedWriter
import java.io.PrintWriter

// The annotated variable will become a private field of the script class. 
@groovy.transform.Field 
PrintWriter writer = null

void call( String msg ) {
    if( ! writer ) {
        def fw = new FileWriter(file, true)
        def bw = new BufferedWriter(fw)
        writer = new PrintWriter(bw)
    }

    try {
        writer.println(msg)
        [...]
    } catch (e) {
        [...]
    }     
}

毕竟,vars文件夹中的脚本被实例化为单例类,非常适合记录器。即使没有@NonCPS注释也可以使用。

管道中的用法很简单:

log 'some message'
© www.soinside.com 2019 - 2024. All rights reserved.