Jenkins Groovy 访问 属性 时出现 StackOverFlowError

Jenkins Groovy StackOverFlowError when accessing a property

我正在尝试编写一个小型作业 DSL,但在访问 class 属性.

时,我遇到了 java.lang.WhosebugError 错误

因此,甚至不需要复杂的脚本。看下面的脚本

class Komponente {

  String name

  Komponente(name) {
    this.name = name
  }

  String getName() {
    return this.name
  }  

  String toString() {
    return 'Klasse: Komponente (name: [' + this.name +'])'
  }
}

Komponente komponente = new Komponente('Testkomponente')

println 'Erstellte Komponente: ' + komponente.getName()

当 运行 它在 Groovy web console 上时它工作正常,但是当 运行 它在我的 Jenkins 上时我得到:

FATAL: null
java.lang.WhosebugError
  at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:1038)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:406)
  at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:677)
  at groovy.lang.GroovyClassLoader$InnerLoader.loadClass(GroovyClassLoader.java:425)
  at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:787)
  at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:775)
  at sun.reflect.GeneratedMethodAccessor316.invoke(Unknown Source)
  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.getProperty(MetaClassImpl.java:1850)
  at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3758)
  at Komponente.getProperty(script)
  at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174)
  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
  at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:290)
  at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
  at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:257)
  at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:288)
  at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
  at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty.callStatic(Unknown Source)
  at Komponente.getName(script:10)
  at sun.reflect.GeneratedMethodAccessor316.invoke(Unknown Source)
  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.getProperty(MetaClassImpl.java:1850)
  at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3758)
  at Komponente.getProperty(script)
  at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174)
  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
  at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:290)
  at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
  at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:257)
  at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:288)
  at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
  at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty.callStatic(Unknown Source)
  at Komponente.getName(script:10)
  ...

  (As you can see this repeates)

如何在 Jenkins 上的 Groovy 脚本 运行 中访问 class 属性,而不会出现 WhosebugError 异常?

我的系统:

我已经搜索过此错误消息,但我发现的所有 Jenkins 问题都已修复并至少在 2.7.1 中关闭,因此应该包含在我的 jenkins 版本中。

从您的 class 中删除 getName() 方法。当您指定 class 字段如 String name 时,您会立即获得方法 String getName()void setName(String name)

请记住 Jenkins Groovy 脚本执行环境与普通的 Groovy 有点不同(例如在 Groovy 控制台中)——Jenkins 使用 groovy-cps 执行环境。

在您的情况下,class org.kohsuke.groovy.sandbox.impl.Checker 导致错误 - 根据您的堆栈跟踪调用 Komponente.getName() 通过以下执行链触发 Komponente.getProperty() 方法:

  at Komponente.getProperty(script)
  at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:174)
  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:456)
  at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:290)
  at org.kohsuke.groovy.sandbox.GroovyInterceptor.onGetProperty(GroovyInterceptor.java:68)
  at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:257)
  at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:288)
  at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
  at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty.callStatic(Unknown Source)
  at Komponente.getName(script:10)

并且 Komponente.getProperty() 触发了 Komponente.getName() 并且您 运行 进入了导致 WhosebugError.

的无限循环

当我将你的 class 复制到我的测试管道脚本时发生了类似的问题,这是我得到的堆栈跟踪:

Started by user admin
[Pipeline] End of Pipeline
java.lang.WhosebugError: Excessively nested closures/functions at Komponente.getName(WorkflowScript:10) - look for unbounded recursion - call depth: 1025
    at com.cloudbees.groovy.cps.impl.CpsFunction.invoke(CpsFunction.java:28)
    at com.cloudbees.groovy.cps.impl.CpsCallableInvocation.invoke(CpsCallableInvocation.java:40)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:62)
    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.GeneratedMethodAccessor106.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[=11=]1(SandboxContinuable.java:19)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.call(SandboxContinuable.java:35)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.call(SandboxContinuable.java:32)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:32)
    at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:331)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access0(CpsThreadGroup.java:82)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:243)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.call(CpsThreadGroup.java:231)
    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:112)
    at jenkins.util.ContextResettingExecutorService.run(ContextResettingExecutorService.java:28)
    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

没有你的那么直接,但也是一样的原因造成的。当我删除 String getName() 方法时,它按预期工作。它也应该对你有用。希望对你有帮助。