「Jenkins Pipeline」- Excessively nested closures

  CREATED BY JENKINSBOT

问题概述

在执行Jenkins Pipeline时,产生如下错误:

java.lang.StackOverflowError: Excessively nested closures/functions at WorkflowScript.getProjectPath(WorkflowScript:16) - 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.GeneratedMethodAccessor345.invoke(Unknown Source)
...

(这个错误信息是从stackoverflow中复制的,与我遇到的问题是同样的场景,只是我后来整理的笔记所以找不到原因了)

本文将介绍该java.lang.StackOverflowError: Excessively nested closures/functions错误的成因及处理方法。

问题原因

这一切都是因为对Groovy语言的不熟悉。产生问题的代码如下:

package com.k4nz.tools

// 我承认我写的代码不够Groovy风格
class Zim {

	private String outputFolder = "/tmp/build"

	public void getOutputFoler() {
		return this.outputFolder
	}
}

问题就处在上面的getOutputFoler()方法。在Groovy中,变量的查找是通过GET方法,也就是说,上述代码等价于:

package com.k4nz.tools

// 我承认我写的代码不够Groovy风格
class Zim {

	private String outputFolder = "/tmp/build"

	public void getOutputFoler() {
		return this.getOutputFolder()
	}
}

这就导致程序进入了无限的递归调用,直至最后的溢出。

在「1.6. Fields and properties/1.6.2. Properties」中描述了这一特性:在Groovy中,遵循JavaBean的约定,但提供了一种更简单的方法来定义属性……

解决办法

重命名方法,或者重命名变量。

因此,以后在Groovy中,使用GET/SET方法要小心,防止进入无限递归调用。

参考文献

Jenkins pipeline throws “StackOverflowError: Excessively nested closures/functions”
1.6. Fields and properties/1.6.2. Properties