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
。使用