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

NPE in CustomToolInstallWrapper.decorateLauncher if launched from pipeline

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • customtools-plugin
    • None

      Problem

      I know that the plugin is not adopted for Jenkins Pipelines yet, but the following line fails with NPE if called properly (with real AbstractBuild children and Launcher as parameters).

      https://github.com/jenkinsci/custom-tools-plugin/blob/45cb1c1a2c8bcce468cc81c7af4f08c6bc0eee10/src/main/java/com/cloudbees/jenkins/plugins/customtools/CustomToolInstallWrapper.java#L169

      final Node node =  Computer.currentComputer().getNode();
      

      The root cause lies in the fact that the pipeline-related code is actually executed on the master thread rather than the agent thread, and this leads to the fact that Computer.currentComputer() always returns null.

      How to Fix

      Simply change that line with the following:

      final Node node = build.getBuiltOn();
      

      I am attaching the Groovy class I was using to solve that issue.
      It nests the original CustomToolInstallWrapper and only overrides decorateLauncher by changing only the given line (other lines are only changed in case of Groovy code style).

      Logs

       [c.l.t.u.p.CustomToolInstallWrapperProxy] Wrapping launcher for RunProxy('test-pipeline #109') on Jenkins...
       [Pipeline] // wrap
       [Pipeline] }
       [Pipeline] // stage
       [Pipeline] }
       [Pipeline] // node
       [Pipeline] End of Pipeline
       java.lang.NullPointerException
       	at com.cloudbees.jenkins.plugins.customtools.CustomToolInstallWrapper.decorateLauncher(CustomToolInstallWrapper.java:169)
       	at com.cloudbees.jenkins.plugins.customtools.CustomToolInstallWrapper$decorateLauncher.call(Unknown Source)
       	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
       	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
       	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:144)
       	at com.lge.tpci.utils.proxy.AbstractWrapperProxy.decorateLauncher(AbstractWrapperProxy.groovy:166)
       	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
       	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
       	at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:169)
       	at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
       	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
       	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
       	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
       	at com.lge.tpci.utils.proxy.AbstractWrapperProxy.wrapContext(AbstractWrapperProxy.groovy:67)
       	at com.lge.tpci.utils.proxy.AbstractWrapperProxy$wrapContext.callCurrent(Unknown Source)
       	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
       	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
       	at com.lge.tpci.utils.proxy.AbstractWrapperProxy.setUp(AbstractWrapperProxy.groovy:141)
       	at org.jenkinsci.plugins.workflow.steps.CoreWrapperStep$Execution2.doStart(CoreWrapperStep.java:117)
       	at org.jenkinsci.plugins.workflow.steps.GeneralNonBlockingStepExecution.lambda$run$0(GeneralNonBlockingStepExecution.java:77)
       	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
       	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
       	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
       	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
       	at java.base/java.lang.Thread.run(Thread.java:829)
       Finished: FAILURE
      

          [JENKINS-69048] NPE in CustomToolInstallWrapper.decorateLauncher if launched from pipeline

          Zaitcev Peter created issue -
          Zaitcev Peter made changes -
          Attachment New: FixedCustomToolInstallWrapper.groovy [ 58510 ]
          Zaitcev Peter made changes -
          Attachment New: pipeline.png [ 58511 ]
          Zaitcev Peter made changes -
          Description Original: h3. Problem
          I know that the plugin is not adopted for Jenkins Pipelines yet, but the following line fails with NPE if called properly (with real AbstractBuild children and Launcher as parameters).

          https://github.com/jenkinsci/custom-tools-plugin/blob/45cb1c1a2c8bcce468cc81c7af4f08c6bc0eee10/src/main/java/com/cloudbees/jenkins/plugins/customtools/CustomToolInstallWrapper.java#L169
          {code:java}
          final Node node = Computer.currentComputer().getNode();
          {code}

          h3. How to Fix
          Simply change that line with the following:
          {code:java}
          final Node node = build.getBuiltOn();
          {code}

          I am attaching the Groovy class I was using to solve that issue.
          It nests the original {{CustomToolInstallWrapper}} and only overrides {{decorateLauncher}} by changing only the given line (other lines are only changed in case of Groovy code style).

          h3. Logs
          {code}
           [c.l.t.u.p.CustomToolInstallWrapperProxy] Wrapping launcher for RunProxy('test-pipeline #109') on Jenkins...
           [Pipeline] // wrap
           [Pipeline] }
           [Pipeline] // stage
           [Pipeline] }
           [Pipeline] // node
           [Pipeline] End of Pipeline
           java.lang.NullPointerException
            at com.cloudbees.jenkins.plugins.customtools.CustomToolInstallWrapper.decorateLauncher(CustomToolInstallWrapper.java:169)
            at com.cloudbees.jenkins.plugins.customtools.CustomToolInstallWrapper$decorateLauncher.call(Unknown Source)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:144)
            at com.lge.tpci.utils.proxy.AbstractWrapperProxy.decorateLauncher(AbstractWrapperProxy.groovy:166)
            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.base/java.lang.reflect.Method.invoke(Method.java:566)
            at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:169)
            at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
            at com.lge.tpci.utils.proxy.AbstractWrapperProxy.wrapContext(AbstractWrapperProxy.groovy:67)
            at com.lge.tpci.utils.proxy.AbstractWrapperProxy$wrapContext.callCurrent(Unknown Source)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
            at com.lge.tpci.utils.proxy.AbstractWrapperProxy.setUp(AbstractWrapperProxy.groovy:141)
            at org.jenkinsci.plugins.workflow.steps.CoreWrapperStep$Execution2.doStart(CoreWrapperStep.java:117)
            at org.jenkinsci.plugins.workflow.steps.GeneralNonBlockingStepExecution.lambda$run$0(GeneralNonBlockingStepExecution.java:77)
            at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
            at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
            at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
            at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
            at java.base/java.lang.Thread.run(Thread.java:829)
           Finished: FAILURE
          {code}
          New: h3. Problem
          I know that the plugin is not adopted for Jenkins Pipelines yet, but the following line fails with NPE if called properly (with real AbstractBuild children and Launcher as parameters).

          https://github.com/jenkinsci/custom-tools-plugin/blob/45cb1c1a2c8bcce468cc81c7af4f08c6bc0eee10/src/main/java/com/cloudbees/jenkins/plugins/customtools/CustomToolInstallWrapper.java#L169
          {code:java}
          final Node node = Computer.currentComputer().getNode();
          {code}

          The root cause lies in the fact that the pipeline-related code is actually executed on the master thread rather than the agent thread, and this leads to the fact that {{Computer.currentComputer()}} always returns {{null}}.

          h3. How to Fix
          Simply change that line with the following:
          {code:java}
          final Node node = build.getBuiltOn();
          {code}

          I am attaching the Groovy class I was using to solve that issue.
          It nests the original {{CustomToolInstallWrapper}} and only overrides {{decorateLauncher}} by changing only the given line (other lines are only changed in case of Groovy code style).

          h3. Logs
          {code}
           [c.l.t.u.p.CustomToolInstallWrapperProxy] Wrapping launcher for RunProxy('test-pipeline #109') on Jenkins...
           [Pipeline] // wrap
           [Pipeline] }
           [Pipeline] // stage
           [Pipeline] }
           [Pipeline] // node
           [Pipeline] End of Pipeline
           java.lang.NullPointerException
            at com.cloudbees.jenkins.plugins.customtools.CustomToolInstallWrapper.decorateLauncher(CustomToolInstallWrapper.java:169)
            at com.cloudbees.jenkins.plugins.customtools.CustomToolInstallWrapper$decorateLauncher.call(Unknown Source)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:144)
            at com.lge.tpci.utils.proxy.AbstractWrapperProxy.decorateLauncher(AbstractWrapperProxy.groovy:166)
            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.base/java.lang.reflect.Method.invoke(Method.java:566)
            at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:169)
            at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
            at com.lge.tpci.utils.proxy.AbstractWrapperProxy.wrapContext(AbstractWrapperProxy.groovy:67)
            at com.lge.tpci.utils.proxy.AbstractWrapperProxy$wrapContext.callCurrent(Unknown Source)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
            at com.lge.tpci.utils.proxy.AbstractWrapperProxy.setUp(AbstractWrapperProxy.groovy:141)
            at org.jenkinsci.plugins.workflow.steps.CoreWrapperStep$Execution2.doStart(CoreWrapperStep.java:117)
            at org.jenkinsci.plugins.workflow.steps.GeneralNonBlockingStepExecution.lambda$run$0(GeneralNonBlockingStepExecution.java:77)
            at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
            at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
            at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
            at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
            at java.base/java.lang.Thread.run(Thread.java:829)
           Finished: FAILURE
          {code}

            Unassigned Unassigned
            hares Zaitcev Peter
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: