Jenkins 脚本化管道:如何在此特定情况下应用@NonCPS 注释
Jenkins scripted Pipeline: How to apply @NonCPS annotation in this specific case
我正在开发一个脚本化的 Jenkins 管道,它需要将具有特定编码的字符串写入文件,如下例所示:
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)
并注释该方法,但这样每次调用该方法时我都必须创建一个新的编写器。
有人知道我该如何改正我的代码吗?
提前致谢!
这里有一种使用 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'
我正在开发一个脚本化的 Jenkins 管道,它需要将具有特定编码的字符串写入文件,如下例所示:
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)
并注释该方法,但这样每次调用该方法时我都必须创建一个新的编写器。
有人知道我该如何改正我的代码吗?
提前致谢!
这里有一种使用 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'