bish
bish

Reputation: 3419

Jenkins Groovy StackOverFlowError when accessing a property

I'm trying to write a small job DSL, but I'm struggling with getting java.lang.StackOverflowError errors when accessing a class property.

Therefore not even a complex script is necessary. See the following script

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()

When running it on the Groovy web console it works fine, but when running it in my Jenkins I get:

FATAL: null
java.lang.StackOverflowError
  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$6.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$6.call(Checker.java:288)
  at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
  at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty$2.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$6.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$6.call(Checker.java:288)
  at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
  at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty$2.callStatic(Unknown Source)
  at Komponente.getName(script:10)
  ...

  (As you can see this repeates)

How can I access a class property in a Groovy script running on Jenkins, without getting StackOverflowError exception?

My system:

I already did some searching for this error message, but all Jenkins-Issues I found were fixed and closed at least in 2.7.1 so should be included in my jenkins version.

Upvotes: 2

Views: 3307

Answers (1)

Szymon Stepniak
Szymon Stepniak

Reputation: 42224

Remove getName() method from your class. When you specify class field like String name you get methods String getName() and void setName(String name) out of the box.

Keep in mind that Jenkins Groovy script execution environment is a little bit different than the plain Groovy (e.g. in Groovy console) - Jenkins uses groovy-cps execution environment.

In your case following class org.kohsuke.groovy.sandbox.impl.Checker caused errors - according to your stack trace calling Komponente.getName() triggered Komponente.getProperty() method through the following execution chain:

  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$6.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$6.call(Checker.java:288)
  at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
  at org.kohsuke.groovy.sandbox.impl.Checker$checkedGetProperty$2.callStatic(Unknown Source)
  at Komponente.getName(script:10)

And Komponente.getProperty() triggered Komponente.getName() and you run into infinite loop that caused StackOverflowError.

Similar problem happened when I copied your class to my test pipeline script, here is the stack trace I got:

Started by user admin
[Pipeline] End of Pipeline
java.lang.StackOverflowError: 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$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: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$001(SandboxContinuable.java:19)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:35)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.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.access$200(CpsThreadGroup.java:82)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:243)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:231)
    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:112)
    at jenkins.util.ContextResettingExecutorService$1.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

It's not that straightforward as yours, but it is caused by the same thing. When I removed String getName() method it worked as expected. It should work for you as well. Hope it helps.

Upvotes: 3

Related Questions