Jenkinsfile - Jenkins 构建用户 getUserName() NullPointerException:无法在空对象 Mutli 分支索引扫描上调用方法 getUserName()
Jenkinsfile - Jenkins build user getUserName() NullPointerException: Cannot invoke method getUserName() on null object Mutli Branch Indexing Scanning
Jenkins 2.138.1.2-rolling --and-- 使用 MultiBranch Pipeline(从 master 构建,分支和拉取请求等)。
我想在构建描述中显示启动构建的 Jenkins 构建作业的用户。
例如:
为了实现相同的功能,在我的 Jenkinsfile
中,我在顶部有以下代码:
@NonCPS
def getBuildUser() {
def build = currentBuild.rawBuild
def cause = build.getCause(hudson.model.Cause.UserIdCause.class)
def BUILD_USER = cause.getUserName()
return BUILD_USER
}
pipeline {
...
}
Class 定义:https://javadoc.jenkins-ci.org/hudson/model/Cause.UserIdCause.html shows the method is NOT Deprecated (like it's in the case of UserCause class).
在 Jenkinsfile 的阶段部分下,我有以下代码,它成功地实现了这个。
stages {
stage ('Start') {
steps {
script {
// Set Build Description
def BUILD_USER= getBuildUser()
currentBuild.description = "${BUILD_USER}: ${RELEASE_TAG} => ${DOCKER_IMAGES}"
}
sh '''
set +x
echo -e "\n\n-- Starting build process.\n"
'''
}
}
.. more stages are here ..
}
因为我正在使用多分支管道作业,所以我看到了所有 branches/PR,包括 master 和侧边栏,我看到了以下链接:
多分支设置扫描周期设置为每10
分钟。
我看到有时 构建失败 并出现以下错误,即 java.lang.NullPointerException: Cannot invoke method getUserName() on null object
和其他时候,构建一直是成功的,构建描述是也不错
[Bitbucket] Build result notified
java.lang.NullPointerException: Cannot invoke method getUserName() 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.call(Checker.java:158)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:160)
at org.kohsuke.groovy.sandbox.impl.Checker$checkedCall.callStatic(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:194)
at WorkflowScript.getBuildUser(WorkflowScript:5)
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 groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
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.call(Checker.java:158)
at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:157)
at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:156)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:160)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:125)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:130)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
at WorkflowScript.run(WorkflowScript:75)
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.fixName(FunctionCallBlock.java:77)
at sun.reflect.GeneratedMethodAccessor333.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.call(Continuable.java:174)
at com.cloudbees.groovy.cps.Continuable.call(Continuable.java:163)
at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access[=12=]1(SandboxContinuable.java:18)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:51)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:347)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access0(CpsThreadGroup.java:93)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:259)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:247)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService.call(CpsVmExecutorService.java:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService.run(SingleLaneExecutorService.java:131)
at jenkins.util.ContextResettingExecutorService.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService.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:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Finished: FAILURE
我注意到,当 Multi-Branch Scanning
/ Branch Indexing
在后台 运行 时,这 仅 发生,因为所有失败构建在该构建号的控制台页面中列出了以下内容。
对于带有构建描述和所有内容的成功构建,上面的“BRANCH INDEXING”框不可见(针对成功构建#)。
为什么我会收到这个 java.lang.NullPointerException: Cannot invoke method getUserName() on null object
错误(当扫描在后台进行时)——或者我该怎么做避免构建失败?
PS:要重现此问题,用户只需单击
Scan Multibranch Pipeline Now 的侧边栏 icon/link 这将导致构建失败,控制台输出显示:
PS:安装新插件可能需要一些时间(1-2 周)/scanning/approval 安全团队的流程,所以不是一个选项我认为,至少在获得批准之前。例如:https://plugins.jenkins.io/build-user-vars-plugin/
为了避免构建失败,现在,我启用了 try
和 catch
并设置了 BUILD_USER 的值,如果 getCause(...)
将会失败 ...有人点击侧边栏 link Scan MultiBranch Pipeline Now
,然后控制台输出或 Jenkins 没有设置在该 侧边点击 的用户- bar link 启动构建(如果有任何要构建的更改)并显示 Branch Indexing
作为输出的第一行(而不是显示:Started by user <some name> (someUserID)
)。
因此,以下内容会将 BUILD_USER 设置为一个有意义的值,并且不会使构建失败。
@NonCPS
def getBuildUser() {
def build = currentBuild.rawBuild
def BUILD_USER = "ToBeSet"
try {
def cause = build.getCause(hudson.model.Cause.UserIdCause.class)
BUILD_USER = cause.getUserName()
} catch(Exception ex) {
println "\n\n-- Build caused by either Multi-Branch Pipeline Scanning -or- Timer i.e. not directly by a logged in user\n";
BUILD_USER = "Multi_Branch_Scan_or_Timer"
}
return BUILD_USER
}
我仍然想知道是否有办法,我们可以找到,谁点击了侧边栏 link(登录用户),就会戳进去。
Jenkins 2.138.1.2-rolling --and-- 使用 MultiBranch Pipeline(从 master 构建,分支和拉取请求等)。
我想在构建描述中显示启动构建的 Jenkins 构建作业的用户。
例如:
为了实现相同的功能,在我的 Jenkinsfile
中,我在顶部有以下代码:
@NonCPS
def getBuildUser() {
def build = currentBuild.rawBuild
def cause = build.getCause(hudson.model.Cause.UserIdCause.class)
def BUILD_USER = cause.getUserName()
return BUILD_USER
}
pipeline {
...
}
Class 定义:https://javadoc.jenkins-ci.org/hudson/model/Cause.UserIdCause.html shows the method is NOT Deprecated (like it's in the case of UserCause class).
在 Jenkinsfile 的阶段部分下,我有以下代码,它成功地实现了这个。
stages {
stage ('Start') {
steps {
script {
// Set Build Description
def BUILD_USER= getBuildUser()
currentBuild.description = "${BUILD_USER}: ${RELEASE_TAG} => ${DOCKER_IMAGES}"
}
sh '''
set +x
echo -e "\n\n-- Starting build process.\n"
'''
}
}
.. more stages are here ..
}
因为我正在使用多分支管道作业,所以我看到了所有 branches/PR,包括 master 和侧边栏,我看到了以下链接:
多分支设置扫描周期设置为每10
分钟。
我看到有时 构建失败 并出现以下错误,即 java.lang.NullPointerException: Cannot invoke method getUserName() on null object
和其他时候,构建一直是成功的,构建描述是也不错
[Bitbucket] Build result notified
java.lang.NullPointerException: Cannot invoke method getUserName() 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.call(Checker.java:158)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:160)
at org.kohsuke.groovy.sandbox.impl.Checker$checkedCall.callStatic(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:194)
at WorkflowScript.getBuildUser(WorkflowScript:5)
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 groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
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.call(Checker.java:158)
at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:157)
at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:156)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:160)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:125)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:130)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
at WorkflowScript.run(WorkflowScript:75)
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.fixName(FunctionCallBlock.java:77)
at sun.reflect.GeneratedMethodAccessor333.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.call(Continuable.java:174)
at com.cloudbees.groovy.cps.Continuable.call(Continuable.java:163)
at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access[=12=]1(SandboxContinuable.java:18)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:51)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:347)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access0(CpsThreadGroup.java:93)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:259)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:247)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService.call(CpsVmExecutorService.java:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService.run(SingleLaneExecutorService.java:131)
at jenkins.util.ContextResettingExecutorService.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService.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:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Finished: FAILURE
我注意到,当 Multi-Branch Scanning
/ Branch Indexing
在后台 运行 时,这 仅 发生,因为所有失败构建在该构建号的控制台页面中列出了以下内容。
对于带有构建描述和所有内容的成功构建,上面的“BRANCH INDEXING”框不可见(针对成功构建#)。
为什么我会收到这个 java.lang.NullPointerException: Cannot invoke method getUserName() on null object
错误(当扫描在后台进行时)——或者我该怎么做避免构建失败?
PS:要重现此问题,用户只需单击
Scan Multibranch Pipeline Now 的侧边栏 icon/link 这将导致构建失败,控制台输出显示:
PS:安装新插件可能需要一些时间(1-2 周)/scanning/approval 安全团队的流程,所以不是一个选项我认为,至少在获得批准之前。例如:https://plugins.jenkins.io/build-user-vars-plugin/
为了避免构建失败,现在,我启用了 try
和 catch
并设置了 BUILD_USER 的值,如果 getCause(...)
将会失败 ...有人点击侧边栏 link Scan MultiBranch Pipeline Now
,然后控制台输出或 Jenkins 没有设置在该 侧边点击 的用户- bar link 启动构建(如果有任何要构建的更改)并显示 Branch Indexing
作为输出的第一行(而不是显示:Started by user <some name> (someUserID)
)。
因此,以下内容会将 BUILD_USER 设置为一个有意义的值,并且不会使构建失败。
@NonCPS
def getBuildUser() {
def build = currentBuild.rawBuild
def BUILD_USER = "ToBeSet"
try {
def cause = build.getCause(hudson.model.Cause.UserIdCause.class)
BUILD_USER = cause.getUserName()
} catch(Exception ex) {
println "\n\n-- Build caused by either Multi-Branch Pipeline Scanning -or- Timer i.e. not directly by a logged in user\n";
BUILD_USER = "Multi_Branch_Scan_or_Timer"
}
return BUILD_USER
}
我仍然想知道是否有办法,我们可以找到,谁点击了侧边栏 link(登录用户),就会戳进去。