简体   繁体   English

从 groovy 脚本调用方法时,我在 Jenkisn 上收到 java.lang.NullPointerException

[英]I am getting java.lang.NullPointerException on Jenkisn while calling method from groovy script

I am trying to call a method of the groovy script from Jenkins pipeline script and in that, I am getting java.lang.NullPointerException: Cannot invoke method getBuildsByDomain() on null object. I am trying to call a method of the groovy script from Jenkins pipeline script and in that, I am getting java.lang.NullPointerException: Cannot invoke method getBuildsByDomain() on null object.

below is my Jenkins script下面是我的 Jenkins 脚本

        pipeline{
          agent any
          environment{
              def EARLIESTDATE = '0'
              def LATESTDATE = '0'
            }
          parameters{
              string(defaultValue: "", description: 'Mention the Jenkins Directory. Like Dev/testforlder or DEV', name: 'JENKINS_DIRECTORY')
              string(defaultValue: "0", description: 'Enter the earliest date. Format: MM/dd/yyyy', name: 'EARLIEST_DATE')
              string(defaultValue: "0", description: 'Enter the earliest date. Format: MM/dd/yyyy', name: 'LATEST_DATE')
            }
            stages{
              stage("Getting Build Details"){
                steps{
                  script{
                    def rootDir = pwd()
                    echo "LOG-->INFO-->Current Working Directory : ${rootDir}"
                    echo "LOG-->INFO-->JENKINS DIRECTORY : ${params.JENKINS_DIRECTORY}"
                    echo "LOG-->INFO-->EARLIEST DATE : ${params.EARLIEST_DATE}"
                    echo "LOG-->INFO-->LATEST DATE : ${params.LATEST_DATE}"
                    def  FILES_LIST = sh (script: "ls   '${rootDir}'", returnStdout: true).trim()
                    //DEBUG
                    echo "FILES_LIST : ${FILES_LIST}"

                    def buildDetails = load "${rootDir}/getJobDetails.groovy"
                    echo "Script: ${buildDetails}"
                    buildDetails.getBuildsByDomain(params.JENKINS_DIRECTORY, params.EARLIEST_DATE, params.LATEST_DATE)
                  }
                }
              }
            }
            post{
              always {
                cleanWs()
              }
            }
        }

and the groovy script /getJobDetails.groovy和 groovy 脚本 /getJobDetails.groovy

        import com.cloudbees.hudson.plugins.folder.Folder
        import jenkins.model.Jenkins
        import java.text.SimpleDateFormat
        import groovy.time.TimeCategory

        /*test=''
        getBuildsByDomain('DEV',test,test)*/

        def getBuildsByDomain(JENKINSDIR,EARLIEST_DATE, LATEST_DATE){
            def buildsByDomain = new Dictionary()

            def jenkinsDir = Jenkins.instance.getItemByFullName(JENKINSDIR)
            echo "LOG-->INFO-->Directory to Check: ${jenkinsDir.getFullName()}"
            def folderObj = getFolders(jenkinsDir)
            //println "Folders to Check: ${folderObj}"

            folderObj.each{ folder ->
                //println "Folder: ${folder.name}"
                def jobObj = getJobs(folder)
                def totatBuilds = []
                //println "Job List: ${jobObj}"
                jobObj.each{job ->
                    def builds = []
                    builds = processJob(job,EARLIEST_DATE, LATEST_DATE)
                    totatBuilds = [totatBuilds, builds].flatten().findAll{it}
                    //println builds
                }
            buildsByDomain.put(folder.name,totatBuilds.size())
            //println "Total Builds: ${totatBuilds}"
            //println "Total Builds Count: ${buildCount = totatBuilds.size()}"
            }
            echo "LOG-->INFO-->Build Details By Domain: ${buildsByDomain}"
            //return buildsByDomain
        }

        def processJob(Item job,EARLIEST_DATE, LATEST_DATE){
            Date earliestDate = EARLIEST_DATE != '0' ? Date.parse('MM/dd/yyyy',EARLIEST_DATE): new Date() -7
            Date latestDate = LATEST_DATE != '0' ? Date.parse('MM/dd/yyyy', LATEST_DATE) : new Date()
            def buildnum = []
            if(job.getLastBuild() != null){
                //println job.name
                job.builds.each{
                    if (it.getTime().compareTo(earliestDate) == 1 && it.getTime().compareTo(latestDate) == -1 ){
                        buildnum.add(it.displayName[1..-1])
                    }
                }
                return buildnum
            }
        }

        def getJobs(Item folder){
            def jobs = []
            folder.getItems().each{
                if(it instanceof com.cloudbees.hudson.plugins.folder.AbstractFolder){
                    getJobs(it)
                }else{
                    jobs.add(it)
                }
            }
          return jobs
        }

        def getFolders(Item directory){
            def folders = []
            directory.getItems().each{
                if(it instanceof com.cloudbees.hudson.plugins.folder.Folder){
                    folders.add(it)
                }
            }
            return folders
        }


        class Dictionary{
            def key
            def value
            def dict = [:]
            // Empty No-arg constructor. Required for the overloaded constructor below
            Dictionary() {}

            // A two-arg constructor to facilitate an entry to be added during instantiation
            Dictionary(key, value) {
            put(key,value)
            }

            // Method to validate the key, value inputs for not-null
            def validate(key, value){
                if(key==null)
                    throw new RuntimeException("groovy-log: Null key is not permitted")
                if(value==null)
                    throw new RuntimeException("groovy-log: Null value is not permitted")
            }

            // Actual method to store the key-value pairs.
            // Exception message printed if any of them is null.
            def put(key, value) {
                try {
                    validate(key,value)
                    this.dict[key]=value
                    printInfo()
                } catch(Exception exception) {
                    println "  #### ERROR #### --> " + exception.getMessage()
                    println " "
                }
            }

            // Overridden toString() to have a meaningful display
            String toString() {
                "Builds Count By Domain : ${dict}"
            }
        }

while runing it I with parameter I am getting below console output在使用参数运行它时,我在控制台 output 下面

            Commit message: "10.02"
            [Pipeline] }
            [Pipeline] // stage
            [Pipeline] withEnv
            [Pipeline] {
            [Pipeline] withEnv
            [Pipeline] {
            [Pipeline] stage
            [Pipeline] { (Getting Build Details)
            [Pipeline] script
            [Pipeline] {
            [Pipeline] pwd
            [Pipeline] echo
            LOG-->INFO-->Current Working Directory : /home/jenkins_agent/jenkins/workspace/Internal Jobs/JenkinsTools/Get_Jenkins_Metrics
            [Pipeline] echo
            LOG-->INFO-->JENKINS DIRECTORY : Dev
            [Pipeline] echo
            LOG-->INFO-->EARLIEST DATE : 0
            [Pipeline] echo
            LOG-->INFO-->LATEST DATE : 0
            [Pipeline] sh
             > git rev-list --no-walk 05d56d2022241f4c883709efb315a41a3d7fd330 # timeout=10
            + ls '/home/jenkins_agent/jenkins/workspace/Internal Jobs/JenkinsTools/Get_Jenkins_Metrics'
            [Pipeline] echo
            FILES_LIST : Achived
            getJobDetails.groovy
            main.jf
            [Pipeline] load
            [Pipeline] { (/home/jenkins_agent/jenkins/workspace/Internal Jobs/JenkinsTools/Get_Jenkins_Metrics/getJobDetails.groovy)
            [Pipeline] }
            [Pipeline] // load
            [Pipeline] echo
            Script: null
            [Pipeline] }
            [Pipeline] // script
            [Pipeline] }
            [Pipeline] // stage
            [Pipeline] stage
            [Pipeline] { (Declarative: Post Actions)
            [Pipeline] cleanWs
            [WS-CLEANUP] Deleting project workspace...
            [WS-CLEANUP] Deferred wipeout is used...
            [WS-CLEANUP] done
            [Pipeline] }
            [Pipeline] // stage
            [Pipeline] }
            [Pipeline] // withEnv
            [Pipeline] }
            [Pipeline] // withEnv
            [Pipeline] }
            [Pipeline] // node
            [Pipeline] End of Pipeline
            java.lang.NullPointerException: Cannot invoke method getBuildsByDomain() on null object
                at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
                at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
                at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
                at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:35)
                at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
                at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
                at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:158)
                at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:160)
                at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
                at WorkflowScript.run(WorkflowScript:27)
                at ___cps.transform___(Native Method)
                at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
                at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
                at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
                at sun.reflect.GeneratedMethodAccessor210.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.lang.reflect.Method.invoke(Method.java:498)
                at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
                at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:76)
                at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
                at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
                at sun.reflect.GeneratedMethodAccessor469.invoke(Unknown Source)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.lang.reflect.Method.invoke(Method.java:498)
                at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
                at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
                at com.cloudbees.groovy.cps.Next.step(Next.java:83)
                at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
                at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
                at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:129)
                at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:268)
                at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
                at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$101(SandboxContinuable.java:34)
                at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.lambda$run0$0(SandboxContinuable.java:59)
                at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:237)
                at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:58)
                at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:182)
                at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332)
                at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83)
                at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244)
                at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232)
                at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
                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)
            Finished: FAILURE

I am not bale to figure out what mistake i am doing.我无法弄清楚我在做什么错误。 Please help me out to debug this.请帮我调试一下。

The only place where you call getBuildsByDomain唯一调用getBuildsByDomain的地方

buildDetails.getBuildsByDomain(params.JENKINS_DIRECTORY...

Means that buildDetails is null表示buildDetails是 null

You are getting buildDetails by loading getJobDetails.groovy您通过加载getJobDetails.groovy来获取buildDetails

But getJobDetails.groovy script returns nothing.但是getJobDetails.groovy脚本什么也没返回。

Normally you should end it with return this通常你应该用return this结束它

As for me the error is pretty clear explained.至于我,这个错误解释得很清楚。 You have NPE because "buildDetails" is null.您有 NPE,因为“buildDetails”是 null。 "buildDetails" is the result of loading "${rootDir}/getJobDetails.groovy". “buildDetails”是加载“${rootDir}/getJobDetails.groovy”的结果。
So I would start with checking ability to load this file for Jenkins.因此,我将从检查为 Jenkins 加载此文件的能力开始。 Existence, permissions etc.存在、权限等

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM