Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-39425

REGRESSION: NPE when calculating getStartTime chunk time

    XMLWordPrintable

Details

    • indian

    Description

      There is a multibranch job taht bwalding runs that fails to show the pipeline stage graph.

      This is due to /runs/N/nodes/ returning a 500 error, which is due to a null pointer exception.
      And has been failing since the update to bismuth.

      The stage view (classic) does not have this problem.

      Still working on how exactly to reproduce this but thought the stack trace may be useful on its own.

      Caused by: java.lang.NullPointerException
      	at org.jenkinsci.plugins.workflow.actions.TimingAction.getStartTime(TimingAction.java:45)
      	at org.jenkinsci.plugins.workflow.pipelinegraphanalysis.StatusAndTiming.computeChunkTiming(StatusAndTiming.java:240)
      	at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.handleChunkDone(PipelineNodeGraphVisitor.java:201)
      	at org.jenkinsci.plugins.workflow.graphanalysis.StandardChunkVisitor.chunkStart(StandardChunkVisitor.java:40)
      	at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.chunkStart(PipelineNodeGraphVisitor.java:74)
      	at org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner.visitSimpleChunks(ForkScanner.java:566)
      	at org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner.visitSimpleChunks(ForkScanner.java:551)
      	at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.<init>(PipelineNodeGraphVisitor.java:68)
      	at io.jenkins.blueocean.rest.impl.pipeline.NodeGraphBuilder$NodeGraphBuilderFactory.getInstance(NodeGraphBuilder.java:37)
      	at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeContainerImpl.<init>(PipelineNodeContainerImpl.java:32)
      	at io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl.getNodes(PipelineRunImpl.java:81)
      	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.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:324)
      	at org.kohsuke.stapler.MetaClass$3.doDispatch(MetaClass.java:196)
      	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
      	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
      

      Attachments

        Issue Links

          Activity

            bwalding Ben Walding added a comment -

            Jenkins 2.28 + BlueOcean b11 - stack trace looks the same - but for the avoidance of doubt

            Caused by: java.lang.NullPointerException
            	at org.jenkinsci.plugins.workflow.actions.TimingAction.getStartTime(TimingAction.java:45)
            	at org.jenkinsci.plugins.workflow.pipelinegraphanalysis.StatusAndTiming.computeChunkTiming(StatusAndTiming.java:240)
            	at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.handleChunkDone(PipelineNodeGraphVisitor.java:201)
            	at org.jenkinsci.plugins.workflow.graphanalysis.StandardChunkVisitor.chunkStart(StandardChunkVisitor.java:40)
            	at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.chunkStart(PipelineNodeGraphVisitor.java:74)
            	at org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner.visitSimpleChunks(ForkScanner.java:566)
            	at org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner.visitSimpleChunks(ForkScanner.java:551)
            	at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.<init>(PipelineNodeGraphVisitor.java:68)
            	at io.jenkins.blueocean.rest.impl.pipeline.NodeGraphBuilder$NodeGraphBuilderFactory.getInstance(NodeGraphBuilder.java:37)
            	at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeContainerImpl.<init>(PipelineNodeContainerImpl.java:32)
            	at io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl.getNodes(PipelineRunImpl.java:81)
            	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.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:335)
            	at org.kohsuke.stapler.MetaClass$3.doDispatch(MetaClass.java:197)
            	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
            	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
            	... 101 more
            

            As a test I created a multibranch pipeline test job that launches a secondary pipeline job (same structure as my failing job) - it did not have the same issue. So there is something subtle about it.

            bwalding Ben Walding added a comment - Jenkins 2.28 + BlueOcean b11 - stack trace looks the same - but for the avoidance of doubt Caused by: java.lang.NullPointerException at org.jenkinsci.plugins.workflow.actions.TimingAction.getStartTime(TimingAction.java:45) at org.jenkinsci.plugins.workflow.pipelinegraphanalysis.StatusAndTiming.computeChunkTiming(StatusAndTiming.java:240) at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.handleChunkDone(PipelineNodeGraphVisitor.java:201) at org.jenkinsci.plugins.workflow.graphanalysis.StandardChunkVisitor.chunkStart(StandardChunkVisitor.java:40) at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.chunkStart(PipelineNodeGraphVisitor.java:74) at org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner.visitSimpleChunks(ForkScanner.java:566) at org.jenkinsci.plugins.workflow.graphanalysis.ForkScanner.visitSimpleChunks(ForkScanner.java:551) at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor.<init>(PipelineNodeGraphVisitor.java:68) at io.jenkins.blueocean.rest.impl.pipeline.NodeGraphBuilder$NodeGraphBuilderFactory.getInstance(NodeGraphBuilder.java:37) at io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeContainerImpl.<init>(PipelineNodeContainerImpl.java:32) at io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl.getNodes(PipelineRunImpl.java:81) 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.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:335) at org.kohsuke.stapler.MetaClass$3.doDispatch(MetaClass.java:197) at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58) at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746) ... 101 more As a test I created a multibranch pipeline test job that launches a secondary pipeline job (same structure as my failing job) - it did not have the same issue. So there is something subtle about it.
            michaelneale Michael Neale added a comment -

            OK did some digging.

            The failure happens here:
            https://github.com/jenkinsci/workflow-api-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/actions/TimingAction.java#L45

            due to flowNode being null.

            The ternary expression https://github.com/jenkinsci/pipeline-graph-analysis-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/pipelinegraphanalysis/StatusAndTiming.java#L240

            does not guard against firstNode being null (I am not sure if the true/false is correct either, but can't comment on that). Clearly firstNode is null, and it is trying to find the timing for it.

            michaelneale Michael Neale added a comment - OK did some digging. The failure happens here: https://github.com/jenkinsci/workflow-api-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/actions/TimingAction.java#L45 due to flowNode being null. The ternary expression https://github.com/jenkinsci/pipeline-graph-analysis-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/pipelinegraphanalysis/StatusAndTiming.java#L240 does not guard against firstNode being null (I am not sure if the true/false is correct either, but can't comment on that). Clearly firstNode is null, and it is trying to find the timing for it.
            michaelneale Michael Neale added a comment - The root cause seems to be that "firstExecuted" is null: https://github.com/jenkinsci/blueocean-plugin/blob/master/blueocean-pipeline-api-impl/src/main/java/io/jenkins/blueocean/rest/impl/pipeline/PipelineNodeGraphVisitor.java#L201 in PipelineNodeGraphVisitor.
            michaelneale Michael Neale added a comment -

            vivek right there is a case where firstExecuted could be null, in fact there is a check for it:

                    TimingInfo times = StatusAndTiming.computeChunkTiming(run, chunk.getPauseTimeMillis(), firstExecuted, chunk.getLastNode(), chunk.getNodeAfter());
            
                    if(times == null){
                        times = new TimingInfo();
                    }
            
                    GenericStatus status = (firstExecuted == null) ? GenericStatus.NOT_EXECUTED :StatusAndTiming
                        .computeChunkStatus(run, chunk.getNodeBefore(), firstExecuted, chunk.getLastNode(), chunk.getNodeAfter());
            
            

            However this check happens after it is attempted to be used to get the timing. It shouldn't be called if null.

            michaelneale Michael Neale added a comment - vivek right there is a case where firstExecuted could be null, in fact there is a check for it: TimingInfo times = StatusAndTiming.computeChunkTiming(run, chunk.getPauseTimeMillis(), firstExecuted, chunk.getLastNode(), chunk.getNodeAfter()); if(times == null){ times = new TimingInfo(); } GenericStatus status = (firstExecuted == null) ? GenericStatus.NOT_EXECUTED :StatusAndTiming .computeChunkStatus(run, chunk.getNodeBefore(), firstExecuted, chunk.getLastNode(), chunk.getNodeAfter()); However this check happens after it is attempted to be used to get the timing. It shouldn't be called if null.
            bwalding Ben Walding added a comment -

            An empty stage triggers it

              stage("for the lulz") {
              
              }
            
            bwalding Ben Walding added a comment - An empty stage triggers it stage("for the lulz") { }
            michaelneale Michael Neale added a comment -

            Have a potential fix incoming...

            michaelneale Michael Neale added a comment - Have a potential fix incoming...
            michaelneale Michael Neale added a comment - Fix pending: https://github.com/jenkinsci/blueocean-plugin/pull/581

            People

              michaelneale Michael Neale
              michaelneale Michael Neale
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: