英文:
I keep running into MissingPropertyException on my Jenkins job although the varibale is defined
问题 {#heading}
错误: 构建步骤失败,出现异常
groovy.lang.MissingPropertyException: 类Script1没有名为manager的属性
在org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:66)处
在org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:51)处
在org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:310)处
在Script1.isAnyJobRunningOrQueued(Script1.groovy:90)处
在Script1$isAnyJobRunningOrQueued.callCurrent(未知源)
在org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)处
在org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)处
在org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:169)处
在Script1.run(Script1.groovy:48)处
在groovy.lang.GroovyShell.evaluate(GroovyShell.java:574)处
在groovy.lang.GroovyShell.evaluate(GroovyShell.java:612)处
在groovy.lang.GroovyShell.evaluate(GroovyShell.java:583)处
在org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:442)处
在org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:379)处
在hudson.plugins.groovy.SystemGroovy.run(SystemGroovy.java:95)处
在hudson.plugins.groovy.SystemGroovy.perform(SystemGroovy.java:59)处
在hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)处
在hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:816)处
在hudson.model.Build$BuildExecution.build(Build.java:199)处
在hudson.model.Build$BuildExecution.doRun(Build.java:164)处
在hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:524)处
在hudson.model.Run.execute(Run.java:1899)处
在hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:44)处
在hudson.model.ResourceController.execute(ResourceController.java:107)处
在hudson.model.Executor.run(Executor.java:449)处
我的代码是为了在没有其他正在运行或排队的作业时运行清理作业-
import hudson.model.*
def runningBuilds = []
def queuedBuilds = []
def manager = Hudson.instance
def queue = manager.queue
if (queue.items.size() > 0) {
queuedBuilds = queue.items.collect { it.task.url }
}
for (computer in manager.computers) {
for (executor in computer.executors) {
if (executor.isBusy()) {
def currentBuildUrl = executor.currentExecutable.url
if (!currentBuildUrl.matches('.*/clean_test/\\d+/'))
runningBuilds << currentBuildUrl
println "excluding current job from running builds: $currentBuildUrl"
}
}
}
}
def maxRetries = 70
def retryIntervalSec = 10
def retries = 0
while (retries < maxRetries) {
if (runningBuilds.isEmpty() && queuedBuilds.isEmpty()) {
break
}
if (retries == maxRetries - 1) {
println "Max retries reached. Exiting..."
return
}
println "Waiting for running and queued builds to complete..."
sleep(retryIntervalSec * 1000)
retries++
}
def queueAfterWait = manager.queue
if (!isAnyJobRunningOrQueued(queueAfterWait)) {
// 在此处添加清理逻辑
println "Running cleanup job on master node..."
println "List current files in /tmp folder"
println runCommand("ls -ltrh /tmp/")
println "-------------------------------------------------------------------------------------------------------------"
def diskSpaceBeforeCleanup = runCommand("ls -ltrh /tmp | head -n 1")
println "TMP folder disk space before cleanup is $diskSpaceBeforeCleanup"
// runCommand("rm -rf /tmp/<files>")
println "-------------------------------------------------------------------------------------------------------------"
def diskSpaceAfterCleanup = runCommand("ls -ltrh /tmp | head -n 1")
println "TMP folder disk space after cleanup is $diskSpaceAfterCleanup"
println "-------------------------------------------------------------------------------------------------------------"
} else {
println "Skipping cleanup as other Jenkins jobs are running or queued."
println "Running builds:"
if (runningBuilds.isEmpty()) {
println "No running builds."
} else {
println runningBuilds.join('\n')
}
println "Queued builds:"
if (queuedBuilds.isEmpty()) {
println "No queued builds."
} else {
println queuedBuilds.join('\n')
}
}
def runCommand(String command) {
def process = command.execute()
process.waitFor()
return process.text.trim()
}
def isAnyJobRunningOrQueued(queue) {
// 检查所有计算机上的运行作业
for (computer in manager.computers) {
for (executor in computer.executors) {
if (executor.isBusy()) {
return true
}
}
}
// 检查排队作业
if (queue.items.size() > 0) {
return true
}
return false
}
尝试使用Jenkins.instance而不是hudson并删除manager
def jenkins = Jenkins.instance
def queue = jenkins.queue
和这个
def queue = Jenkins.instance.queue
但我仍然看到错误
groovy.lang.MissingPropertyException: 类Script1没有名为Jenkins的属性
在org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:66)处
在org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:51)处
在org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:310)处
在Script1.run(Script1.groovy:6)处
<details>
<summary>英文:</summary>
ERROR: Build step failed with exception
groovy.lang.MissingPropertyException: No such property: manager for class: Script1
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:66)
at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:310)
at Script1.isAnyJobRunningOrQueued(Script1.groovy:90)
at Script1$isAnyJobRunningOrQueued.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:169)
at Script1.run(Script1.groovy:48)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:574)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:612)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:583)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:442)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:379)
at hudson.plugins.groovy.SystemGroovy.run(SystemGroovy.java:95)
at hudson.plugins.groovy.SystemGroovy.perform(SystemGroovy.java:59)
at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:816)
at hudson.model.Build$BuildExecution.build(Build.java:199)
at hudson.model.Build$BuildExecution.doRun(Build.java:164)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:524)
at hudson.model.Run.execute(Run.java:1899)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:44)
at hudson.model.ResourceController.execute(ResourceController.java:107)
at hudson.model.Executor.run(Executor.java:449)
My code is for a cleanup to run when no other jobs are running or queued except for the cleanup job-
import hudson.model.*
def runningBuilds = []
def queuedBuilds = []
def manager = Hudson.instance
def queue = manager.queue
if (queue.items.size() > 0) {
queuedBuilds = queue.items.collect { it.task.url }
}
for (computer in manager.computers) {
for (executor in computer.executors) {
if (executor.isBusy()) {
def currentBuildUrl = executor.currentExecutable.url
if (!currentBuildUrl.matches('.*/clean_test/\d+/'))
runningBuilds << currentBuildUrl
println "excluding current job from running builds: $currentBuildUrl"
}
}
}
}
def maxRetries = 70
def retryIntervalSec = 10
def retries = 0
while (retries < maxRetries) {
if (runningBuilds.isEmpty() && queuedBuilds.isEmpty()) {
break
}
if (retries == maxRetries - 1) {
println "Max retries reached. Exiting..."
return
}
println "Waiting for running and queued builds to complete..."
sleep(retryIntervalSec * 1000)
retries++
}
def queueAfterWait = manager.queue
if (!isAnyJobRunningOrQueued(queueAfterWait)) {
// Your cleanup logic here
println "Running cleanup job on master node..."
println "List current files in /tmp folder"
println runCommand("ls -ltrh /tmp/")
println "-------------------------------------------------------------------------------------------------------------"
def diskSpaceBeforeCleanup = runCommand("ls -ltrh /tmp | head -n 1")
println "TMP folder disk space before cleanup is $diskSpaceBeforeCleanup"
// runCommand("rm -rf /tmp/<files>")
println "-------------------------------------------------------------------------------------------------------------"
def diskSpaceAfterCleanup = runCommand("ls -ltrh /tmp | head -n 1")
println "TMP folder disk space after cleanup is $diskSpaceAfterCleanup"
println "-------------------------------------------------------------------------------------------------------------"
} else {
println "Skipping cleanup as other Jenkins jobs are running or queued."
println "Running builds:"
if (runningBuilds.isEmpty()) {
println "No running builds."
} else {
println runningBuilds.join('\n')
}
println "Queued builds:"
if (queuedBuilds.isEmpty()) {
println "No queued builds."
} else {
println queuedBuilds.join('\n')
}
}
def runCommand(String command) {
def process = command.execute()
process.waitFor()
return process.text.trim()
}
def isAnyJobRunningOrQueued(queue) {
// Check running builds on all computers
for (computer in manager.computers) {
for (executor in computer.executors) {
if (executor.isBusy()) {
return true
}
}
}
// Check queued builds
if (queue.items.size() > 0) {
return true
}
return false
}
Tried using Jenkins.instance instead of hudson and removed manager as well
def jenkins = Jenkins.instance
def queue = jenkins.queue
and this-
def queue = Jenkins.instance.queue
But I still see errors
groovy.lang.MissingPropertyException: No such property: Jenkins for class: Script1
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:66)
at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:310)
at Script1.run(Script1.groovy:6)
</details>
# 答案1
**得分**: 1
这段代码的一部分看起来有问题:
```groovy
def isAnyJobRunningOrQueued(queue) {
// 检查所有计算机上运行的构建
for (computer in manager.computers) {
你在方法中使用了脚本变量 manager
,但没有将其作为参数传递。你可以尝试将其改成如下所示:
def isAnyJobRunningOrQueued(queue, manager) {
// 检查所有计算机上运行的构建
for (computer in manager.computers) {
并且修改 isAnyJobRunningOrQueued
方法的调用:
if (!isAnyJobRunningOrQueued(queueAfterWait, manager)) {
希望这对你有所帮助。
更新:
另一种选项是将 manager
声明为全局变量,而不是 def manager = bla-bla
。以下是一个小的测试脚本,以便你了解 Groovy 中局部变量和全局变量的工作方式:
def scriptVar = '我是局部变量'
globalVar = '我是全局变量!'
someMethod()
def someMethod() {
// println "scriptVar = $scriptVar" -- 这将失败!!!
println "globalVar = $globalVar"
}
英文:
To me this part of code looks suspicious:
def isAnyJobRunningOrQueued(queue) {
// Check running builds on all computers
for (computer in manager.computers) {
----------
You're using script variable manager
in the method without passing it as a parameter. Could you try to change it to:
def isAnyJobRunningOrQueued(queue, manager) {
// Check running builds on all computers
for (computer in manager.computers) {
----------
and change the call of the isAnyJobRunningOrQueued
method:
if (!isAnyJobRunningOrQueued(queueAfterWait, manager)) {
-------
I hope it will help.
Update:
Another option is to declare manager
as a global variable manager = bla-bla
instead of def manager = bla-bla
. Here is the small test script so you get the idea how local and global variables work in Groovy:
def scriptVar = 'I am local'
globalVar = "I'm global!"
someMethod()
def someMethod() {
// println "scriptVar = $scriptVar" -- it fails!!!
println "globalVar = $globalVar"
}