Jenkins 管道 java.io.NotSerializableException java.util.regex.Matcher 错误,即使使用 @NonCPS
Jenkins pipeline java.io.NotSerializableException java.util.regex.Matcher error even with @NonCPS
我在执行正则表达式匹配的 Jenkinsfile
函数前面使用 @NonCPS
,即使使用 @NonCPS
注释,我仍然收到 java.io.NotSerializableException java.util.regex.Matcher
错误。
注意,它多次调用该函数,只有在实际匹配时才会出现异常。
这是我的代码:
@NonCPS
def extractEndTime(logLine) {
def MY_REGEX = /.*(20[0-9]{2}-[0-9]{2}-[0-9]{2}).([0-9]{2}:[0-9]{2}:[0-9]{2}).*\"\w+\"\sthe text\s(\w+)\./
m = (logLine =~ TEST_LOGLINE_END_REGEX)
if (m.count) {
return [m[1],m[2],m[3]]
} else {
return null
}
}
执行 jenkins 构建时的输出:
GitHub has been notified of this commit’s build result
java.io.NotSerializableException: java.util.regex.Matcher
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333)
at java.util.HashMap.writeObject(HashMap.java:1354)
at sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at com.cloudbees.groovy.cps.SerializableScript.writeObject(SerializableScript.java:26)
at sun.reflect.GeneratedMethodAccessor145.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.HashMap.internalWriteEntries(HashMap.java:1777)
at java.util.HashMap.writeObject(HashMap.java:1354)
at sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:132)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:433)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:412)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:357)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access0(CpsThreadGroup.java:78)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:236)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:224)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService.call(CpsVmExecutorService.java:63)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService.run(SingleLaneExecutorService.java:112)
at jenkins.util.ContextResettingExecutorService.run(ContextResettingExecutorService.java:28)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: an exception which occurred:
in field delegate
in field closures
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@42b37962
Finished: FAILURE
可能是由于 m
变量范围。
尝试像这样用 def
限制它:
def m = (logLine =~ TEST_LOGLINE_END_REGEX)
如果没有 def
,变量将在全局脚本绑定中创建,因此在退出该方法后仍然存在。
Jenkins 要求所有变量都是可序列化的,因为在服务器重启等中断情况下,管道的状态会定期保存到磁盘。此功能允许管道保持其状态并在服务器重新启动后继续。 Matcher 类型的变量不可序列化,需要开发人员进行一些额外的工作。
From jenkinsci/pipeline-plugin Serializing Local Variables:
However the safest approach is to isolate use of nonserializable state
inside a method marked with the annotation @NonCPS. Such a method will
be treated as “native” by the Pipeline engine, and its local variables
never saved.
提供的代码示例:
@NonCPS
def version(text) {
def matcher = text =~ '<version>(.+)</version>'
matcher ? matcher[0][1] : null
}
可以在 Pipeline Groovy Plugin Technical Design 上找到其他 material 支持,他们在这里讨论了更多技术细节和标记为 @NonCPS
的方法的行为。
Pipeline scripts may mark designated methods with the annotation
@NonCPS. These are then compiled normally (except for sandbox security
checks), and so behave much like “binary” methods from the Java
Platform, Groovy runtime, or Jenkins core or plugin code. @NonCPS
methods may safely use non-Serializable objects as local variables,
though they should not accept nonserializable parameters or return or
store nonserializable values. You may not call regular
(CPS-transformed) methods, or Pipeline steps, from a @NonCPS method,
so they are best used for performing some calculations before passing
a summary back to the main script. Note in particular that @Overrides
of methods defined in binary classes, such as Object.toString(),
should in general be marked @NonCPS since it will commonly be binary
code calling them.
参见:Serializing Local Variables
和 Pipeline Groovy Plugin Technical Design
为清楚起见,以下对我有用。
开发人员的额外工作,例如,请参见下面的代码。
my.Parameter 不可序列化
所以我创建了一个没有 def 的方法并将其注释为 @NonCPS 并从节点块中调用它
node('MySys') {
echo 'hello'
avoidCPS()
echo 'finished'
}
@NonCPS
avoidCPS () {
// use my.Parameter here
my.Parameter p = new my.Parameter()
... do some more ...
}
以下作品(注意[0]
):
def m = (it =~ /abcd/)[0]
但这会导致 java.io.NotSerializableException
:
def m = (it =~ /abcd/)
运行最近进入这个。避免这种情况的一种方法是在将需要的部分提取到可序列化类型中后,简单地将本地匹配器对象设置为 null。在执行其他 steps/actions.
之前确保它为 null
script {
def label = 'v1.2.3' // From git describe etc.
def regex = '^v([0-9]+).([0-9]+).([0-9]+)$'
def matcher = label =~ regex
if (matcher) {
def tag = matcher[0][0]
def maj = matcher[0][1] as int
def min = matcher[0][2] as int
def patch = matcher[0][3] as int
matcher = null
echo "Found ${maj} ${min} ${patch} from ${tag}"
// Additional steps
} else {
matcher = null
echo "Nothing found"
}
}
我在执行正则表达式匹配的 Jenkinsfile
函数前面使用 @NonCPS
,即使使用 @NonCPS
注释,我仍然收到 java.io.NotSerializableException java.util.regex.Matcher
错误。
注意,它多次调用该函数,只有在实际匹配时才会出现异常。
这是我的代码:
@NonCPS
def extractEndTime(logLine) {
def MY_REGEX = /.*(20[0-9]{2}-[0-9]{2}-[0-9]{2}).([0-9]{2}:[0-9]{2}:[0-9]{2}).*\"\w+\"\sthe text\s(\w+)\./
m = (logLine =~ TEST_LOGLINE_END_REGEX)
if (m.count) {
return [m[1],m[2],m[3]]
} else {
return null
}
}
执行 jenkins 构建时的输出:
GitHub has been notified of this commit’s build result
java.io.NotSerializableException: java.util.regex.Matcher
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333)
at java.util.HashMap.writeObject(HashMap.java:1354)
at sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at com.cloudbees.groovy.cps.SerializableScript.writeObject(SerializableScript.java:26)
at sun.reflect.GeneratedMethodAccessor145.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.HashMap.internalWriteEntries(HashMap.java:1777)
at java.util.HashMap.writeObject(HashMap.java:1354)
at sun.reflect.GeneratedMethodAccessor116.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:132)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:433)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:412)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:357)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access0(CpsThreadGroup.java:78)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:236)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:224)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService.call(CpsVmExecutorService.java:63)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService.run(SingleLaneExecutorService.java:112)
at jenkins.util.ContextResettingExecutorService.run(ContextResettingExecutorService.java:28)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: an exception which occurred:
in field delegate
in field closures
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@42b37962
Finished: FAILURE
可能是由于 m
变量范围。
尝试像这样用 def
限制它:
def m = (logLine =~ TEST_LOGLINE_END_REGEX)
如果没有 def
,变量将在全局脚本绑定中创建,因此在退出该方法后仍然存在。
Jenkins 要求所有变量都是可序列化的,因为在服务器重启等中断情况下,管道的状态会定期保存到磁盘。此功能允许管道保持其状态并在服务器重新启动后继续。 Matcher 类型的变量不可序列化,需要开发人员进行一些额外的工作。
From jenkinsci/pipeline-plugin Serializing Local Variables:
However the safest approach is to isolate use of nonserializable state inside a method marked with the annotation @NonCPS. Such a method will be treated as “native” by the Pipeline engine, and its local variables never saved.
提供的代码示例:
@NonCPS
def version(text) {
def matcher = text =~ '<version>(.+)</version>'
matcher ? matcher[0][1] : null
}
可以在 Pipeline Groovy Plugin Technical Design 上找到其他 material 支持,他们在这里讨论了更多技术细节和标记为 @NonCPS
的方法的行为。
Pipeline scripts may mark designated methods with the annotation @NonCPS. These are then compiled normally (except for sandbox security checks), and so behave much like “binary” methods from the Java Platform, Groovy runtime, or Jenkins core or plugin code. @NonCPS methods may safely use non-Serializable objects as local variables, though they should not accept nonserializable parameters or return or store nonserializable values. You may not call regular (CPS-transformed) methods, or Pipeline steps, from a @NonCPS method, so they are best used for performing some calculations before passing a summary back to the main script. Note in particular that @Overrides of methods defined in binary classes, such as Object.toString(), should in general be marked @NonCPS since it will commonly be binary code calling them.
参见:Serializing Local Variables 和 Pipeline Groovy Plugin Technical Design
为清楚起见,以下对我有用。
开发人员的额外工作,例如,请参见下面的代码。
my.Parameter 不可序列化
所以我创建了一个没有 def 的方法并将其注释为 @NonCPS 并从节点块中调用它
node('MySys') {
echo 'hello'
avoidCPS()
echo 'finished'
}
@NonCPS
avoidCPS () {
// use my.Parameter here
my.Parameter p = new my.Parameter()
... do some more ...
}
以下作品(注意[0]
):
def m = (it =~ /abcd/)[0]
但这会导致 java.io.NotSerializableException
:
def m = (it =~ /abcd/)
运行最近进入这个。避免这种情况的一种方法是在将需要的部分提取到可序列化类型中后,简单地将本地匹配器对象设置为 null。在执行其他 steps/actions.
之前确保它为 nullscript {
def label = 'v1.2.3' // From git describe etc.
def regex = '^v([0-9]+).([0-9]+).([0-9]+)$'
def matcher = label =~ regex
if (matcher) {
def tag = matcher[0][0]
def maj = matcher[0][1] as int
def min = matcher[0][2] as int
def patch = matcher[0][3] as int
matcher = null
echo "Found ${maj} ${min} ${patch} from ${tag}"
// Additional steps
} else {
matcher = null
echo "Nothing found"
}
}