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 added a comment - - edited

          In order to call it, however, I was forced to implement JobProxy, RunProxy, and AbstractWrapperProxy classes. First two cast WorkflowProject and WorkflowRun into AbstractProject and AbstractRun respectively, and the third one casts BuildWrapper into SimpleBuildWrapper. Also I was forced to explicitly pass node name from pipeline's environment. However, it worked!

           Running on Jenkins in /var/lib/jenkins/workspace/test-pipeline
           [Pipeline] {
           [Pipeline] stage
           [Pipeline] { (Tools Setup)
           [Pipeline] wrap
           [c.l.t.u.p.CustomToolInstallWrapperProxy] Calling original setup...
           [c.l.t.u.p.CustomToolInstallWrapperProxy] Wrapping launcher for RunProxy('test-pipeline #131') on Jenkins...
           [CustomTools] - gerrit-repo: Starting installation
           [gerrit-repo] $ sh -e /var/lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/hudson5704092191006562509.sh
             % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                            Dload  Upload   Total   Spent    Left  Speed
           
            0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
          100 45277  100 45277    0     0   129k      0 --:--:-- --:--:-- --:--:--  129k
           mode of '.bin/repo' retained as 0755 (rwxr-xr-x)
           [c.l.t.u.p.CustomToolInstallWrapperProxy] Extracting variables from launcher...
           $ printenv -0
           [c.l.t.u.p.CustomToolInstallWrapperProxy] Adding extra environment...
           [c.l.t.u.p.CustomToolInstallWrapperProxy] Adding disposer...
           [Pipeline] {
           [Pipeline] sh (Verify Gerrit Repo installation)
           + echo PATH: /var/lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo:/var/lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/.bin::/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
           PATH: /var/lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo:/var/lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/.bin::/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
           + which repo
           /var/lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/.bin/repo
           + echo 'repo' util found
           'repo' util found
           + repo --version
           <repo not installed>
           repo launcher version 2.21
                  (from /var/lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/.bin/repo)
           git 2.25.1
           Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
           [GCC 9.4.0]
           OS Linux 4.4.0-210-generic (#242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021)
           CPU x86_64 (x86_64)
           Bug reports: https://bugs.chromium.org/p/gerrit/issues/entry?template=Repo+tool+issue
           [Pipeline] }
           [Pipeline] // wrap
           [Pipeline] }
           [Pipeline] // stage
           [Pipeline] }
           [Pipeline] // node
           [Pipeline] End of Pipeline
           Finished: SUCCESS
          

          Zaitcev Peter added a comment - - edited In order to call it, however, I was forced to implement JobProxy , RunProxy , and AbstractWrapperProxy classes. First two cast WorkflowProject and WorkflowRun into AbstractProject and AbstractRun respectively, and the third one casts BuildWrapper into SimpleBuildWrapper . Also I was forced to explicitly pass node name from pipeline's environment. However, it worked! Running on Jenkins in / var /lib/jenkins/workspace/test-pipeline [Pipeline] { [Pipeline] stage [Pipeline] { (Tools Setup) [Pipeline] wrap [c.l.t.u.p.CustomToolInstallWrapperProxy] Calling original setup... [c.l.t.u.p.CustomToolInstallWrapperProxy] Wrapping launcher for RunProxy( 'test-pipeline #131' ) on Jenkins... [CustomTools] - gerrit-repo: Starting installation [gerrit-repo] $ sh -e / var /lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/hudson5704092191006562509.sh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 45277 100 45277 0 0 129k 0 --:--:-- --:--:-- --:--:-- 129k mode of '.bin/repo' retained as 0755 (rwxr-xr-x) [c.l.t.u.p.CustomToolInstallWrapperProxy] Extracting variables from launcher... $ printenv -0 [c.l.t.u.p.CustomToolInstallWrapperProxy] Adding extra environment... [c.l.t.u.p.CustomToolInstallWrapperProxy] Adding disposer... [Pipeline] { [Pipeline] sh (Verify Gerrit Repo installation) + echo PATH: / var /lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo:/ var /lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/.bin::/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games PATH: / var /lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo:/ var /lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/.bin::/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games + which repo / var /lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/.bin/repo + echo 'repo' util found 'repo' util found + repo --version <repo not installed> repo launcher version 2.21 (from / var /lib/jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/gerrit-repo/.bin/repo) git 2.25.1 Python 3.8.10 ( default , Mar 15 2022, 12:22:08) [GCC 9.4.0] OS Linux 4.4.0-210- generic (#242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021) CPU x86_64 (x86_64) Bug reports: https: //bugs.chromium.org/p/gerrit/issues/entry?template=Repo+tool+issue [Pipeline] } [Pipeline] // wrap [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS

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

              Created:
              Updated: