Jenkins 为什么在尝试从常规管道作业启动多分支构建作业时会出现异常?
我正在做一些类似于被接受的回应。我有一个常规管道作业,它试图为已经扫描和注册的特定分支启动多分支管道作业 代码如下所示:Jenkins 为什么在尝试从常规管道作业启动多分支构建作业时会出现异常?,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,我正在做一些类似于被接受的回应。我有一个常规管道作业,它试图为已经扫描和注册的特定分支启动多分支管道作业 代码如下所示: rc = build job: mb_job_name, wait: true 其中mb_job_name包含下游作业的名称加上分支名称 奇怪的是,下游作业实际上启动并运行良好。我看到了预期的结果: Scheduling project: playground-sandbox » Chris » test-jenkins-mb » dv_main_117_
rc = build job: mb_job_name,
wait: true
其中mb_job_name
包含下游作业的名称加上分支名称
奇怪的是,下游作业实际上启动并运行良好。我看到了预期的结果:
Scheduling project: playground-sandbox » Chris » test-jenkins-mb » dv_main_117_chris2
输出。问题是,在我启动下游作业的常规管道作业中,就在构建作业调用之后,以及预期的调度。。。输出时,它会引发如下异常:
an exception which occurred:
in field com.cloudbees.groovy.cps.impl.BlockScopeEnv.locals
in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@28280b21
in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@48fc924d
in field com.cloudbees.groovy.cps.impl.CallEnv.caller
in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@3b112c7a
in field com.cloudbees.groovy.cps.Continuable.e
in object org.jenkinsci.plugins.workflow.cps.SandboxContinuable@a5e88d8
in field org.jenkinsci.plugins.workflow.cps.CpsThread.program
in object org.jenkinsci.plugins.workflow.cps.CpsThread@6faa034a
in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.threads
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@d6a022e
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@d6a022e
Caused: java.io.NotSerializableException: groovy.json.internal.LazyMap
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:926)
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:1793)
at java.util.HashMap.writeObject(HashMap.java:1363)
at sun.reflect.GeneratedMethodAccessor124.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:156)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:191)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1028)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1019)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1019)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1019)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
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.concurrent.ConcurrentSkipListMap.writeObject(ConcurrentSkipListMap.java:1437)
at sun.reflect.GeneratedMethodAccessor146.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:156)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:191)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1028)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
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.lambda$writeObject$0(RiverWriter.java:144)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:237)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:143)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:553)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:530)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgramIfPossible(CpsThreadGroup.java:517)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:441)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:96)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:312)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:276)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:136)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
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:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Finished: FAILURE
在一般意义上,我理解这意味着我有Jenkins无法序列化的代码/变量,但我不清楚它是什么
我尝试将代码更改为更简单的形式:
build mb_job_name
我还尝试用带有作业名称的字符串文字替换mb_job_name变量,但没有改进
更新
这似乎与我在生成调用之前有以下代码有关:
def jsonSlurper = new JsonSlurper()
def pl = jsonSlurper.parseText(payload)
def repo_name = pl.repository.name
如果我删除
def jsonSlurper=new jsonSlurper()
,那么我将不再获得异常。不幸的是,我需要解析一些JSON,所以我需要创建一个对象。可能需要以某种方式使用@NonCPS注释。Jenkins中的多分支作业文件夹结构不同于常规作业,要从远程作业触发该结构,必须指定“JOBNAME/BRANCHNAME”。
可能是你在格式上弄错了,所以它是错误的。看看我下面的例子
node {
stage('call multibranch pipeline') {
def res = build job:'test0/main'
}
}
在我的示例中,test0
-是多分支作业名称,main
是分支。我没有使用wait:true
,因为wait
默认值在build
DSL中为true
输出
Jenkins中的多分支作业文件夹结构不同于常规作业,要从远程作业触发该结构,必须指定“JOBNAME/BRANCHNAME”。 可能是你在格式上弄错了,所以它是错误的。看看我下面的例子
node {
stage('call multibranch pipeline') {
def res = build job:'test0/main'
}
}
在我的示例中,test0
-是多分支作业名称,main
是分支。我没有使用wait:true
,因为wait
默认值在build
DSL中为true
输出
如果要在管道代码中使用
JsonSlurper
,请改用JsonSlurperClassic
。不同之处在于,第二个生成可序列化的对象LinkedHashMap
。第一个生成不可序列化的LazyMap
在管道代码中解析JSON有不同的方法,您可以查看此博客文章以了解更多信息-如果您想在管道代码中使用
JsonSlurper
,请改用JsonSlurperClassic
。不同之处在于,第二个生成可序列化的对象LinkedHashMap
。第一个生成不可序列化的LazyMap
在管道代码中解析JSON有不同的方法,您可以查看这篇博客文章以了解更多信息-正如您所提到的,您需要使用@NonCPS告诉Jenkins CPS它处于无法序列化程序状态的状态。这是通过将不可序列化的代码移动到函数中来实现的:
@NonCPS
def parseRepositoryName(payload) {
def jsonSlurper = new JsonSlurper()
def pl = jsonSlurper.parseText(payload)
return pl.repository.name
}
def repo_name = parseRepositoryName(payload)
将此添加到代码末尾,并用对新函数的函数调用替换旧的json解析代码:
@NonCPS
def parseRepositoryName(payload) {
def jsonSlurper = new JsonSlurper()
def pl = jsonSlurper.parseText(payload)
return pl.repository.name
}
def repo_name = parseRepositoryName(payload)
正如您所提到的,您需要使用@NonCPS告诉Jenkins CPS它处于无法序列化程序状态的状态。这是通过将不可序列化的代码移动到函数中来实现的:
@NonCPS
def parseRepositoryName(payload) {
def jsonSlurper = new JsonSlurper()
def pl = jsonSlurper.parseText(payload)
return pl.repository.name
}
def repo_name = parseRepositoryName(payload)
将此添加到代码末尾,并用对新函数的函数调用替换旧的json解析代码:
@NonCPS
def parseRepositoryName(payload) {
def jsonSlurper = new JsonSlurper()
def pl = jsonSlurper.parseText(payload)
return pl.repository.name
}
def repo_name = parseRepositoryName(payload)
谢谢是的,我本来就有这个问题,如果你只指定没有分支的作业名称,它会启动扫描,这对我来说非常有用。但这并不导致例外。仅当我将异常指定为“job/branch”时,才会得到该异常。有趣的是,你没有看到错误。我基本上也在做同样的事情。我在输出中看到了调度项目:行,但没有看到“开始构建:”行。谢谢。是的,我本来就有这个问题,如果你只指定没有分支的作业名称,它会启动扫描,这对我来说非常有用。但这并不导致例外。仅当我将异常指定为“job/branch”时,才会得到该异常。有趣的是,你没有看到错误。我基本上也在做同样的事情。我在输出中看到了调度项目:行,但没有看到“开始构建:”行。我们也尝试过这个。但它不起作用。也许这也完全取决于jenkins的版本。如果您仍然出现序列化错误,那么您还有更多的代码需要放在NonCPS块中。谢谢。这个解决方案也很有效,但我选择使用JsonSlurperClassic作为最佳答案,因为它需要更少的代码更改和更大的灵活性。我不得不将函数的最后一行更改为
return(pl.repository.name)
。现有的return=…
代码导致了一个错误。请充分理解,我们也尝试了这个方法。但它不起作用。也许这也完全取决于jenkins的版本。如果您仍然出现序列化错误,那么您还有更多的代码需要放在NonCPS块中。谢谢。这个解决方案也很有效,但我选择使用JsonSlurperClassic作为最佳答案,因为它需要更少的代码更改和更大的灵活性。我不得不将函数的最后一行更改为return(pl.repository.name)
。现有的return=…
代码导致错误。请完全理解使用readJSON
实用程序步骤而不是JsonSlurper
。使用