[JIRA] (JENKINS-60115) NullPointerException in Declarative Pipeline after upgrade from 1.3.9 to 1.4.0

10 views
Skip to first unread message

pverheyden@broadleafcommerce.com (JIRA)

unread,
Nov 8, 2019, 7:27:04 PM11/8/19
to jenkinsc...@googlegroups.com
Phillip Verheyden created an issue
 
Jenkins / Bug JENKINS-60115
NullPointerException in Declarative Pipeline after upgrade from 1.3.9 to 1.4.0
Issue Type: Bug Bug
Assignee: Andrew Bayer
Components: pipeline-model-definition-plugin
Created: 2019-11-09 00:26
Environment: Java 8, Jenkins kubernetes over JNLP
Priority: Minor Minor
Reporter: Phillip Verheyden

After the upgrade to 1.4.0, my builds started to fail with a NullPointerException when parsing the model. Here's the full stack trace:

 

java.lang.NullPointerExceptionava.lang.NullPointerException at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStep.withOrWithoutParens(ModelASTStep.java:111) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStep.toGroovy(ModelASTStep.java:100) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTElement.toGroovy(ModelASTElement.java:142) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBranch.toGroovy(ModelASTBranch.java:41) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStage.toGroovy(ModelASTStage.java:115) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTElement.toGroovy(ModelASTElement.java:142) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTElement.toGroovyBlock(ModelASTElement.java:213) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStages.toGroovy(ModelASTStages.java:44) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTElement.toGroovy(ModelASTElement.java:122) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTPipelineDef.toGroovy(ModelASTPipelineDef.java:58) at org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTMarkerInterface$toGroovy.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer$Wrapper.<init>(RuntimeASTTransformer.groovy:1077) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83) at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:255) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer.transform(RuntimeASTTransformer.groovy:90) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.RuntimeASTTransformer$transform.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:141) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.ModelParser.parsePipelineStep(ModelParser.groovy:269) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.ModelParser$_parse_closure5.doCall(ModelParser.groovy:168) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022) at groovy.lang.Closure.call(Closure.java:414) at groovy.lang.Closure.call(Closure.java:430) at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:3202) at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:3172) at org.codehaus.groovy.runtime.dgm$67.invoke(Unknown Source) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.ModelParser.parse(ModelParser.groovy:167) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.ModelParser$parse.callCurrent(Unknown Source) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.ModelParser.parse(ModelParser.groovy:124) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.ModelParser.parse(ModelParser.groovy) at org.jenkinsci.plugins.pipeline.modeldefinition.parser.GroovyShellDecoratorImpl$1.call(GroovyShellDecoratorImpl.java:78) at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1065)Caused: BUG! exception in phase 'semantic analysis' in source unit '/var/jenkins_home/jobs/BroadleafCommerce/jobs/CartOperationServices/branches/PR-134/builds/6/libs/broadleaf-pipeline-library/vars/mavenBuild.groovy' unexpected NullpointerException at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1070) at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603) at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581) at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558) at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298) at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268) at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:254) at groovy.lang.GroovyClassLoader.recompile(GroovyClassLoader.java:761) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:718) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:787) at java.lang.ClassLoader.loadClass(ClassLoader.java:411) at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell$TimingLoader.loadClass(CpsGroovyShell.java:170) at java.lang.ClassLoader.loadClass(ClassLoader.java:411) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:677) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:787) at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:775) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at org.jboss.marshalling.AbstractClassResolver.loadClass(AbstractClassResolver.java:123) at org.jboss.marshalling.AbstractClassResolver.resolveClass(AbstractClassResolver.java:104) at org.jboss.marshalling.river.RiverUnmarshaller.doReadClassDescriptor(RiverUnmarshaller.java:1022) at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1355) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:220) at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1853) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1767) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1715) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1715) at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1395) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:220) at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1853) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1767) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1715) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1715) at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1395) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:220) at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1853) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1767) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1715) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1715) at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1395) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272) at org.jboss.marshalling.river.BlockUnmarshaller.readObject(BlockUnmarshaller.java:149) at org.jboss.marshalling.river.BlockUnmarshaller.readObject(BlockUnmarshaller.java:135) at org.jboss.marshalling.MarshallerObjectInputStream.readObjectOverride(MarshallerObjectInputStream.java:53) at org.jboss.marshalling.river.RiverObjectInputStream.readObjectOverride(RiverObjectInputStream.java:307) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:425) at java.util.HashMap.readObject(HashMap.java:1412) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callReadObject(JDKSpecific.java:179) at org.jboss.marshalling.reflect.SerializableClass.callReadObject(SerializableClass.java:212) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1746) at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1395) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:220) at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1853) at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1767) at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1395) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272) at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:205) at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41) at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverReader$SandboxedUnmarshaller.lambda$readObject$0(RiverReader.java:250) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:237) at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverReader$SandboxedUnmarshaller.sandbox(RiverReader.java:237) at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverReader$SandboxedUnmarshaller.readObject(RiverReader.java:250) at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution$2.onSuccess(CpsFlowExecution.java:783) at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution$2.onSuccess(CpsFlowExecution.java:776) at org.jenkinsci.plugins.workflow.support.concurrent.Futures$1.run(Futures.java:150) at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:149) at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:134) at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:170) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture.access$000(ChainingListenableFuture.java:33) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture$1.run(ChainingListenableFuture.java:196) at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:149) at com.google.common.util.concurrent.ExecutionList.add(ExecutionList.java:105) at com.google.common.util.concurrent.AbstractFuture.addListener(AbstractFuture.java:155) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture.run(ChainingListenableFuture.java:189) at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:149) at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:134) at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:170) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture.access$000(ChainingListenableFuture.java:33) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture$1.run(ChainingListenableFuture.java:196) at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:149) at com.google.common.util.concurrent.ExecutionList.add(ExecutionList.java:105) at com.google.common.util.concurrent.AbstractFuture.addListener(AbstractFuture.java:155) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture.run(ChainingListenableFuture.java:189) at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:149) at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:134) at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:170) at org.jenkinsci.plugins.workflow.support.concurrent.ListFuture.setOneValue(ListFuture.java:158) at org.jenkinsci.plugins.workflow.support.concurrent.ListFuture.access$000(ListFuture.java:40) at org.jenkinsci.plugins.workflow.support.concurrent.ListFuture$2.run(ListFuture.java:107) at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:149) at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:134) at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:170) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture.access$000(ChainingListenableFuture.java:33) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture$1.run(ChainingListenableFuture.java:196) at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:149) at com.google.common.util.concurrent.ExecutionList.add(ExecutionList.java:105) at com.google.common.util.concurrent.AbstractFuture.addListener(AbstractFuture.java:155) at org.jenkinsci.plugins.workflow.support.concurrent.ChainingListenableFuture.run(ChainingListenableFuture.java:189) at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) at com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair.execute(ExecutionList.java:149) at com.google.common.util.concurrent.ExecutionList.execute(ExecutionList.java:134) at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:170) at org.jenkinsci.plugins.workflow.support.pickles.TryRepeatedly.access$500(TryRepeatedly.java:48) at org.jenkinsci.plugins.workflow.support.pickles.TryRepeatedly$1.run(TryRepeatedly.java:112) at jenkins.security.ImpersonatingScheduledExecutorService$1.run(ImpersonatingScheduledExecutorService.java:58) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)Caused: java.io.IOException: Failed to load build state at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution$3.onSuccess(CpsFlowExecution.java:855) at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution$3.onSuccess(CpsFlowExecution.java:853) at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution$4$1.run(CpsFlowExecution.java:907) at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$1.run(CpsVmExecutorService.java:38) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131) 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) 

 

I suppose I could post my entire shared library pipeline, but I need to strip some things out of it. I would rather self-diagnose but I do not know how. Is there any other logging or anything I could turn on that would tell me which class in my library is the problematic one?

Add Comment Add Comment
 
This message was sent by Atlassian Jira (v7.13.6#713006-sha1:cc4451f)
Atlassian logo

bitwiseman@gmail.com (JIRA)

unread,
Nov 14, 2019, 1:06:02 PM11/14/19
to jenkinsc...@googlegroups.com

bitwiseman@gmail.com (JIRA)

unread,
Nov 14, 2019, 5:14:02 PM11/14/19
to jenkinsc...@googlegroups.com
Liam Newman commented on Bug JENKINS-60115
 
Re: NullPointerException in Declarative Pipeline after upgrade from 1.3.9 to 1.4.0

Thanks! Yes, I would appreciate a look at your pipeline.  It shouldn't be all the code in your shared library, just the whatever is in in your pipline directive.
 
I see where the error is being thrown, but it doesn't help me understand the underlying cause.
 

pverheyden@broadleafcommerce.com (JIRA)

unread,
Nov 14, 2019, 11:34:05 PM11/14/19
to jenkinsc...@googlegroups.com

Thanks for the response, sorry for the cloak and dagger.

My pipeline script is a bit unique in that this is what my Jenkinsfile looks like in all my projects:

mavenBuild{ } 

And then I have a shared library that has a `vars/mavenBuild.groovy` that has the declarative pipeline in it. Pasted below.

import com.broadleafcommerce.jenkins.DependentProject
import com.broadleafcommerce.jenkins.DependentProjectDiscoverer
import com.broadleafcommerce.jenkins.ReleaseUtils
import com.broadleafcommerce.jenkins.SonarUtils
import com.broadleafcommerce.jenkins.Utils

def call(body) {
  // evaluate the body block, and collect configuration into the object
  def pipelineParams = [:]
  body.resolveStrategy = Closure.DELEGATE_FIRST
  body.delegate = pipelineParams
  body()

  println "Building with Jenkinsfile settings: $pipelineParams"
  Utils.abortPreviousUpstreamBuilds(currentBuild)

  def extraBuildProfiles = pipelineParams.extraBuildProfiles ?: ''
  def extraDeployProfiles = pipelineParams.extraDeployProfiles ?: ''
  def sonarAnalysis = pipelineParams.sonarAnalysis ?: ''
  def javadocsDirectories = pipelineParams.javadocsDirectories ?: []
  def referenceDocsDirectories = pipelineParams.referenceDocsDirectories ?: []
  def agentLabel = pipelineParams.agentLabel ?: 'maven-jdk8'
  def requiresNpmrc = pipelineParams.requiresNpmrc != null ? pipelineParams.requiresNpmrc : false
  def forceDeploy = pipelineParams.forceDeploy != null ? pipelineParams.forceDeploy : false

  def mainBranch = Utils.isMainBranch(this)
  def shouldDeploy = mainBranch || forceDeploy || params.FORCE_DEPLOY || params.IS_RELEASE_BUILD
  def mavenVersion = '3.6'

  pipeline {

    parameters {
      string(
        // Disabling the classpathURLCheck is for a bug in OpenJDK that prevents Surefire from running properly
        // see https://stackoverflow.com/questions/53010200/maven-surefire-could-not-find-forkedbooter-class/53016532

        defaultValue: '-Xmx2048m -Djdk.net.URLClassPath.disableClassPathURLCheck=true',
        name: 'MAVEN_OPTS',
        description: 'JVM parameters passed to Maven as MAVEN_OPTS'
      )
      string(
        // Disabling the classpathURLCheck is for a bug in OpenJDK that prevents Surefire from running properly
        // see https://stackoverflow.com/questions/53010200/maven-surefire-could-not-find-forkedbooter-class/53016532

        defaultValue: '',
        name: 'MAVEN_BUILD_ARGS',
        description: 'Arguments passed directly to the Maven process (like -X, -e, any extra -D arguments etc). Only applies to the build phase on CI builds, applies to _both_ release:prepare and release:perform on release builds'
      )
      booleanParam(
        defaultValue: false,
        name: 'IS_RELEASE_BUILD',
        description: 'Indicate whether or not this build should be treated as a release'
          +' (GA, milestone, etc) If you would like to validate the versions that are autogenerated,'
          +' use VALIDATE_RELEASE_VERSION_DEFAULTS. Otherwise, current release version (in conjunction'
          +' with the RELEASE_BUILD_QUALIFIER) and next SNAPSHOT version will be autodetected.'
      )
      string(
        defaultValue: 'GA',
        name: 'RELEASE_BUILD_QUALIFIER',
        description: 'Only used in release builds for next and current version calculations'
      )
      booleanParam(
        defaultValue: false,
        name: 'FORCE_DEPLOY',
        description: 'By default, non-release builds only auto-deploy to Nexus from branches named develop-x.y.'
          +' This executes a deploy regardles of what the branch is with whatever version is currently in the pom.'
      )
      booleanParam(
        defaultValue: false,
        name: 'VALIDATE_RELEASE_VERSION_DEFAULTS',
        description: 'Only used when IS_RELEASE_BUILD is true. Pauses the job and waits for the user to confirm whether or not the autodiscovered version numbers are correct for the release.'
      )
    }

    agent {
      label agentLabel
    }

    options {
      buildDiscarder(logRotator(artifactDaysToKeepStr: '1', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '15'))
    }

    stages {

      /**
       * Common to all build types
       */
      stage('Project Validation') {
        steps {
          script {
            def lastCommit = sh returnStdout: true, script: 'git log -1 --pretty=%B'
            if (lastCommit.contains("[maven-release-plugin] prepare release")) {
                println 'Maven Release build detected, aborting build'
                currentBuild.result = 'ABORTED'
                return
            }

            // <scm> must match this repository
            def pom = readMavenPom()
            def scm = pom.scm
            if (!scm) {
              error("An <scm> section is required in your pom.xml")
            }
            if (!scm.connection.startsWith('scm:git:')) {
              error("Only git repositories are supported. Ensure that the <scm> section in your pom.xml starts with scm:git:<url>")
            }
            if (!scm.connection.equalsIgnoreCase("scm:git:${env.GIT_URL}")) {
              error("The <scm> section in pom.xml must match the repository being cloned. Expected: scm:git:${env.GIT_URL} but found ${scm.connection}")
            }

            // mvnw must exist and be executable
            def mvnwUnixExists = fileExists 'mvnw'
            def mvnwWindowsExists = fileExists 'mvnw.cmd'
            if (!mvnwUnixExists || !mvnwWindowsExists) {
              error("There must be both mvnw and mvnw.cmd executables at the root of the repository. This can be initialized by executing 'mvn -N io.takari:maven:wrapper'")
            }
            def mvnwUnixFile = sh returnStdout: true, script: 'ls -l mvnw'.trim()
            def mvnwWindowsFile = sh returnStdout: true, script: 'ls -l mvnw.cmd'.trim()
            if (!mvnwUnixFile.contains('x') || !mvnwWindowsFile.contains('x')) {
              error("The mvnw or mvnw.cmd file is not executable. Run 'chmod +x mvnw mvnw.cmd' in the root of the repository and push the changes to resolve this")
            }

            if (Utils.isMainBranch(this) && forceDeploy) {
              error("The currently executing branch is already a main branch and will be deployed. Remove the forceDeploy parameter from the Jenkinsfile")
            }
          }
        }
      }

      /**
       *
       *  RELEASE STAGES
       *
       */
      stage('Prepare release version') {
        when { expression { return params.IS_RELEASE_BUILD } }
        steps {
          milestone null
          withMaven(maven: "$mavenVersion", mavenSettingsConfig: 'mvn-settings.xml', mavenOpts: params.MAVEN_OPTS) {
            script {
              def requestedQualifier = params.RELEASE_BUILD_QUALIFIER
              def pom = readMavenPom()

              // Set as environment variables to propagate to next stages
              env.release = ReleaseUtils.nextReleaseVersion(pom.version, requestedQualifier)
              env.nextSnapshot = ReleaseUtils.incrementVersion(pom.version, requestedQualifier)
              env.nextRelease = ReleaseUtils.nextReleaseVersion(release, requestedQualifier)
              env.tag = pom.artifactId + '-' + release

              if (params.VALIDATE_RELEASE_VERSION_DEFAULTS) {
                  def userInput
                  timeout(time: 90, unit: 'SECONDS') {
                    userInput = input(
                      id: 'userInput', message: 'Release Properties', parameters: [
                      [$class: 'TextParameterDefinition', defaultValue: release, description: 'The version you are about to release', name: 'release'],
                      [$class: 'TextParameterDefinition', defaultValue: nextSnapshot, description: 'The next development version that the pom will be changed to after completing the release', name: 'nextSnapshot'],
                      [$class: 'TextParameterDefinition', defaultValue: tag, description: 'The tag that will show up in the repository for the release', name: 'tag'],
                      [$class: 'TextParameterDefinition', defaultValue: nextRelease, description: 'What the next release wil be after this one. Used to update milestones and labels automatically on GitHub', name: 'nextRelease']
                    ])
                  }

                  env.release = userInput['release']
                  env.nextSnapshot = userInput['nextSnapshot']
                  env.nextRelease = userInput['nextRelease']
                  env.tag = userInput['tag']
              }

              // this makes commits, need to configure Git
              sh 'git config --replace-all user.email em...@domain.com'
              sh 'git config --replace-all user.name Git User'

              try {
                sh "mvn release:prepare ${params.MAVEN_BUILD_ARGS} -DpushChanges=false -Dresume=false -Dtag=$env.tag -DreleaseVersion=$env.release -DdevelopmentVersion=$env.nextSnapshot -DpreparationGoals='clean initialize spotless:apply verify' -DcompletionGoals='spotless:apply' -Darguments='-Ddockerfile.tag=$env.release'"
              } catch(Exception e) {
                // only rollback if we have .releaseBackup files
                def backupFiles = findFiles glob: '*.releaseBackup'
                if (backupFiles.length > 0) {
                  sh "mvn -DpushChanges=false release:rollback -Dtag=$env.tag -DreleaseVersion=$env.release -DdevelopmentVersion=$env.nextSnapshot"
                  error("The release has failed but it is possible that the repository has already been tagged. The pom has been reverted back but you must manually verify the tag is removed from the repository before retrying to release")
                }
                throw e
              }
            }
          }
        }
      }

      stage("Perform and deploy the release") {
        when { expression { return params.IS_RELEASE_BUILD } }
        steps {
          milestone null
          withMaven(maven: "$mavenVersion", mavenSettingsConfig: 'mvn-settings.xml', mavenOpts: params.MAVEN_OPTS) {
            // GPG signing obtained originally from https://wiki.eclipse.org/EE4J_Build#Example_pipeline_build_job_.28for_GPG_signing.29
            withCredentials([file(credentialsId: 'gpg', variable: 'KEYRING')]) {
              sh 'gpg --batch --import "${KEYRING}"'
              sh 'for fpr in $(gpg --list-keys --with-colons  | awk -F: \'/fpr:/ {print $10}\' | sort -u); do echo -e "5\ny\n" |  gpg --batch --command-fd 0 --expert --edit-key ${fpr} trust; done'

              // Perform the Maven deploy
              sshagent(['github-ssh']) {
                // using -DlocalCheckout makes it so we can prevent a push until the very very end
                sh "mvn release:perform ${params.MAVEN_BUILD_ARGS} -Dresume=false -DlocalCheckout=true -Dtag=$env.tag -DreleaseVersion=$env.release -DdevelopmentVersion=$env.nextSnapshot"
              }
            }
          }

          // now that the build is on the Nexus, push the changes to the Git repo
          sshagent(['github-ssh']) {
            sh "git push origin $env.BRANCH_NAME"
            sh 'git push origin --tags'
          }
        }
      }

      /**
       *
       *  CI STAGES
       *
       */
      stage('Build') {
        when { expression { return !params.IS_RELEASE_BUILD } }
        steps {
          script {
            milestone null

            withMaven(maven: "$mavenVersion", mavenSettingsConfig: 'mvn-settings.xml', mavenOpts: params.MAVEN_OPTS) {
              withCredentials([string(credentialsId: 'GITHUB_AUTH_TOKEN', variable: 'TOKEN')]) {
                def mavenExec = { Map args ->
                  sh "mvn -U clean verify $args.buildArgs -Pcoverage -Pjavadocs $args.additionalProfiles"
                }
                def build = requiresNpmrc ? { buildArgs -> withNPM(npmrcConfig: 'npmrc') { mavenExec(buildArgs) }} : mavenExec

                def pom = readMavenPom()
                DependentProject[] dependentProjects = new DependentProjectDiscoverer().getDependentProjects(pom, TOKEN, this)
                if (dependentProjects) {
                  String modifiedArtifactRoot = mavenDependentBuild(dependentProjects, pom.artifactId, build, [buildArgs: params.MAVEN_BUILD_ARGS, additionalProfiles: extraBuildProfiles])
                  env.CURRENT_ARTIFACT_ROOT = modifiedArtifactRoot
                  env.DEPENDENT_CHECKOUT = true
                } else {
                  build([buildArgs: params.MAVEN_BUILD_ARGS, additionalProfiles: extraBuildProfiles])
                  env.CURRENT_ARTIFACT_ROOT = '.'
                }
              }
            }
          }
        }
      }

      stage('Sonar Analysis') {
        when { expression { return sonarAnalysis != 'skip' && !params.IS_RELEASE_BUILD } }
        steps {
          milestone null
          withMaven(maven: "$mavenVersion", mavenSettingsConfig: 'mvn-settings.xml', mavenOpts: params.MAVEN_OPTS) {
            withSonarQubeEnv('Sonar') {
              sh "mvn -f $env.CURRENT_ARTIFACT_ROOT sonar:sonar ${SonarUtils.getAnalysisParameters(this).join(' ')}"
            }
          }
          // It's possible that the analysis succeeds _very_ quickly before it even gets to the next phase
          // Need to sleep in-between https://community.sonarsource.com/t/need-a-sleep-between-withsonarqubeenv-and-waitforqualitygate-or-it-spins-in-in-progress/2265/8
          echo 'Sleeping for 5 seconds so Sonar can complete the background task'
          sleep(5)
        }
      }

      stage('Sonar Quality Gate') {
        when { expression { return sonarAnalysis != 'skip' && !params.IS_RELEASE_BUILD } }
        steps {
          milestone null
          timeout(time: 2, unit: 'MINUTES') {
            waitForQualityGate abortPipeline: false
          }
        }
      }

      stage('Deploy artifact, sources, javadocs to Nexus') {
        when { expression { return !params.IS_RELEASE_BUILD } }
        steps {
          script {
            milestone null
            // GPG signing obtained originally from https://wiki.eclipse.org/EE4J_Build#Example_pipeline_build_job_.28for_GPG_signing.29
            withCredentials([file(credentialsId: 'gpg', variable: 'KEYRING')]) {
              sh 'gpg --batch --import "${KEYRING}"'
              sh 'for fpr in $(gpg --list-keys --with-colons  | awk -F: \'/fpr:/ {print $10}\' | sort -u); do echo -e "5\ny\n" |  gpg --batch --command-fd 0 --expert --edit-key ${fpr} trust; done'

              withMaven(maven: "$mavenVersion", mavenSettingsConfig: 'mvn-settings.xml', mavenOpts: params.MAVEN_OPTS) {

                def dockerTag = Utils.getDistTag(this, params.IS_RELEASE_BUILD)

                // not a normal main branch, need to do some transformation
                if (!Utils.isMainBranch(this)) {
                  def pom = readMavenPom()
                  def branchSpecificVersion = Utils.getBranchSpecificVersion(this, pom.version)

                  println "Transforming version from $pom.version to a branch-specific version $branchSpecificVersion"
                  sh "mvn -f $env.CURRENT_ARTIFACT_ROOT versions:set -DnewVersion=${branchSpecificVersion} -DgenerateBackupPoms"
                  dockerTag = "branch-${Utils.getSanitizedBranchName(this)}-latest-snapshot"
                }

                sh "mvn -f $env.CURRENT_ARTIFACT_ROOT -Danimal.sniffer.skip=true -DskipTests -DdeployAtEnd=true -Psources -Pjavadocs -Pdocs -Psign-artifacts -Ddockerfile.tag=${dockerTag} $extraDeployProfiles deploy"
              }
            }
          }
        }
      }

      /**
       *
       * Common final stages
       *
       */
      stage('Upload Javadocs site') {
        when { expression { return javadocsDirectories && shouldDeploy } }
        steps {
          milestone null
          script {
            def prefix = params.IS_RELEASE_BUILD ? 'target/checkout/' : ''
            javadocsDirectories.each {
              uploadDocsFile("${prefix}${it}/*-javadoc.jar", 'javadocs')
            }
          }
        }
      }

      stage('Upload Reference docs site') {
        when { expression { return referenceDocsDirectories && shouldDeploy } }
        steps {
          milestone null
          script {
            def prefix = params.IS_RELEASE_BUILD ? 'target/checkout/' : ''
            referenceDocsDirectories.each {
              uploadDocsFile("${prefix}${it}/*-reference.zip", 'docs')
            }
          }
        }
      }
    }

    post {
      failure {
        slackFailureNotification()
      }
      success {
        slackSuccessNotification()
        supersedeBranchCheck()
      }
    }
  }
}

def uploadDocsFile(def file, def host) {
  withCredentials([
    sshUserPrivateKey(credentialsId: "docs-upload-ssh", keyFileVariable: 'keyfile')
  ]) {
    // ignore host checking
    sh "scp -i ${keyfile} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${file} jenkins@${host}:"
    sh "ssh -i ${keyfile} -t -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null jenkins@${host} './extractDocs.sh'"
  }
}
 

bitwiseman@gmail.com (JIRA)

unread,
Nov 15, 2019, 12:56:03 PM11/15/19
to jenkinsc...@googlegroups.com

The issue is cause by literal "null" values in your pipeline text, so it probably due to the milestone null calls.

Could you try this version of the plugin? https://repo.jenkins-ci.org/incrementals/org/jenkinsci/plugins/pipeline-model-api/1.5.0-beta2-rc1705.52ffd0571b96/
It should stop the crash.

I still need to see if I can create a test the reproduces the issue.

pverheyden@gmail.ccom (JIRA)

unread,
Nov 16, 2019, 10:34:02 AM11/16/19
to jenkinsc...@googlegroups.com

Yup the issue was the milestone null for sure. Threw in the version of the plugin you linked at that fixed it! Thanks!

By the way, the reason I even did that in the first place was because of JENKINS-47729 because I didn't want to add an ordinal or name to my milestones.

bitwiseman@gmail.com (JIRA)

unread,
Nov 25, 2019, 11:29:03 AM11/25/19
to jenkinsc...@googlegroups.com

bitwiseman@gmail.com (JIRA)

unread,
Nov 25, 2019, 11:29:03 AM11/25/19
to jenkinsc...@googlegroups.com

bitwiseman@gmail.com (JIRA)

unread,
Dec 4, 2019, 8:31:05 AM12/4/19
to jenkinsc...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages