Jenkins 脚本流水线 @NonCPS 和 StackOverflowError
Jenkins scripted pipleline @NonCPS and StackOverflowError
我有简单的管道脚本:
#!groovy
@org.jenkinsci.plugins.workflow.libs.Library('Some@lib')
import com.cloudbees.groovy.cps.NonCPS
node() {
echo CheekyEnum.getByName('name1').getName()
}
enum CheekyEnum {
ENUM_1('name1', 'f1'),
ENUM_2('name2', 'f2')
String name
String field
CheekyEnum(String name, String field) {
this.name = name
this.field = field
}
static CheekyEnum getByName(String name) {
return values().find { it.name == name }
}
String getName() {
return name
}
}
当我运行一切正常,但如果方法有一点改变getName()
@NonCPS
String getName() {
return name
}
我得到一个很长的错误堆栈跟踪:
java.lang.WhosebugError
at java.lang.ClassLoader.loadClass(ClassLoader.java:398)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxResolvingClassLoader.lambda$loadClass[=12=](SandboxResolvingClassLoader.java:51)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxResolvingClassLoader.lambda$load(SandboxResolvingClassLoader.java:85)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$doComputeIfAbsent(BoundedLocalCache.java:2337)
at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1892)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.doComputeIfAbsent(BoundedLocalCache.java:2335)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2318)
at com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:111)
at com.github.benmanes.caffeine.cache.LocalManualCache.get(LocalManualCache.java:54)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxResolvingClassLoader.load(SandboxResolvingClassLoader.java:79)
...
为什么? @NonCPS
不就是把方法排除在CPS转换之外吗?
enum 本身 是一个可序列化的类型。所以你最好为它创建一个包装函数:
import com.cloudbees.groovy.cps.NonCPS
node() {
echo getName(CheekyEnum.getByName('name1'))
}
...
@NonCPS
String getName(CheekyEnum cheeky) {
return cheeky.name
}
相关的 WhosebugError 可能 是 workflow-cps-plugin. Please take a look at its Technical design
中的 bug/smell
Pipeline scripts may mark designated methods with the annotation @NonCPS. These are then compiled normally (except for sandbox security checks).
AFAICS 您 运行 在 Groovy 沙箱中。沙箱拦截器
可能正在产生这个堆栈溢出。 运行 在沙盒之外也应该可以解决您的问题。
顺便说一句,您还可以阅读 Pipeline CPS Method Mismatches 以更好地理解在非 CPS 转换代码中可以调用什么。
我有简单的管道脚本:
#!groovy
@org.jenkinsci.plugins.workflow.libs.Library('Some@lib')
import com.cloudbees.groovy.cps.NonCPS
node() {
echo CheekyEnum.getByName('name1').getName()
}
enum CheekyEnum {
ENUM_1('name1', 'f1'),
ENUM_2('name2', 'f2')
String name
String field
CheekyEnum(String name, String field) {
this.name = name
this.field = field
}
static CheekyEnum getByName(String name) {
return values().find { it.name == name }
}
String getName() {
return name
}
}
当我运行一切正常,但如果方法有一点改变getName()
@NonCPS
String getName() {
return name
}
我得到一个很长的错误堆栈跟踪:
java.lang.WhosebugError
at java.lang.ClassLoader.loadClass(ClassLoader.java:398)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxResolvingClassLoader.lambda$loadClass[=12=](SandboxResolvingClassLoader.java:51)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxResolvingClassLoader.lambda$load(SandboxResolvingClassLoader.java:85)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$doComputeIfAbsent(BoundedLocalCache.java:2337)
at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1892)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.doComputeIfAbsent(BoundedLocalCache.java:2335)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2318)
at com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:111)
at com.github.benmanes.caffeine.cache.LocalManualCache.get(LocalManualCache.java:54)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxResolvingClassLoader.load(SandboxResolvingClassLoader.java:79)
...
为什么? @NonCPS
不就是把方法排除在CPS转换之外吗?
enum 本身 是一个可序列化的类型。所以你最好为它创建一个包装函数:
import com.cloudbees.groovy.cps.NonCPS
node() {
echo getName(CheekyEnum.getByName('name1'))
}
...
@NonCPS
String getName(CheekyEnum cheeky) {
return cheeky.name
}
相关的 WhosebugError 可能 是 workflow-cps-plugin. Please take a look at its Technical design
中的 bug/smellPipeline scripts may mark designated methods with the annotation @NonCPS. These are then compiled normally (except for sandbox security checks).
AFAICS 您 运行 在 Groovy 沙箱中。沙箱拦截器 可能正在产生这个堆栈溢出。 运行 在沙盒之外也应该可以解决您的问题。
顺便说一句,您还可以阅读 Pipeline CPS Method Mismatches 以更好地理解在非 CPS 转换代码中可以调用什么。