我不断遇到”MissingPropertyException”错误,尽管变量已定义。

huangapple go评论101阅读模式
英文:

I keep running into MissingPropertyException on my Jenkins job although the varibale is defined

问题

错误: 构建步骤失败,出现异常
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)处

我的代码是为了在没有其他正在运行或排队的作业时运行清理作业-

  1. import hudson.model.*
  2. def runningBuilds = []
  3. def queuedBuilds = []
  4. def manager = Hudson.instance
  5. def queue = manager.queue
  6. if (queue.items.size() > 0) {
  7. queuedBuilds = queue.items.collect { it.task.url }
  8. }
  9. for (computer in manager.computers) {
  10. for (executor in computer.executors) {
  11. if (executor.isBusy()) {
  12. def currentBuildUrl = executor.currentExecutable.url
  13. if (!currentBuildUrl.matches('.*/clean_test/\\d+/'))
  14. runningBuilds << currentBuildUrl
  15. println "excluding current job from running builds: $currentBuildUrl"
  16. }
  17. }
  18. }
  19. }
  20. def maxRetries = 70
  21. def retryIntervalSec = 10
  22. def retries = 0
  23. while (retries < maxRetries) {
  24. if (runningBuilds.isEmpty() && queuedBuilds.isEmpty()) {
  25. break
  26. }
  27. if (retries == maxRetries - 1) {
  28. println "Max retries reached. Exiting..."
  29. return
  30. }
  31. println "Waiting for running and queued builds to complete..."
  32. sleep(retryIntervalSec * 1000)
  33. retries++
  34. }
  35. def queueAfterWait = manager.queue
  36. if (!isAnyJobRunningOrQueued(queueAfterWait)) {
  37. // 在此处添加清理逻辑
  38. println "Running cleanup job on master node..."
  39. println "List current files in /tmp folder"
  40. println runCommand("ls -ltrh /tmp/")
  41. println "-------------------------------------------------------------------------------------------------------------"
  42. def diskSpaceBeforeCleanup = runCommand("ls -ltrh /tmp | head -n 1")
  43. println "TMP folder disk space before cleanup is $diskSpaceBeforeCleanup"
  44. // runCommand("rm -rf /tmp/<files>")
  45. println "-------------------------------------------------------------------------------------------------------------"
  46. def diskSpaceAfterCleanup = runCommand("ls -ltrh /tmp | head -n 1")
  47. println "TMP folder disk space after cleanup is $diskSpaceAfterCleanup"
  48. println "-------------------------------------------------------------------------------------------------------------"
  49. } else {
  50. println "Skipping cleanup as other Jenkins jobs are running or queued."
  51. println "Running builds:"
  52. if (runningBuilds.isEmpty()) {
  53. println "No running builds."
  54. } else {
  55. println runningBuilds.join('\n')
  56. }
  57. println "Queued builds:"
  58. if (queuedBuilds.isEmpty()) {
  59. println "No queued builds."
  60. } else {
  61. println queuedBuilds.join('\n')
  62. }
  63. }
  64. def runCommand(String command) {
  65. def process = command.execute()
  66. process.waitFor()
  67. return process.text.trim()
  68. }
  69. def isAnyJobRunningOrQueued(queue) {
  70. // 检查所有计算机上的运行作业
  71. for (computer in manager.computers) {
  72. for (executor in computer.executors) {
  73. if (executor.isBusy()) {
  74. return true
  75. }
  76. }
  77. }
  78. // 检查排队作业
  79. if (queue.items.size() > 0) {
  80. return true
  81. }
  82. return false
  83. }

尝试使用Jenkins.instance而不是hudson并删除manager

  1. def jenkins = Jenkins.instance
  2. def queue = jenkins.queue

和这个

  1. 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)处

  1. <details>
  2. <summary>英文:</summary>
  3. ERROR: Build step failed with exception
  4. groovy.lang.MissingPropertyException: No such property: manager for class: Script1
  5. at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:66)
  6. at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:51)
  7. at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:310)
  8. at Script1.isAnyJobRunningOrQueued(Script1.groovy:90)
  9. at Script1$isAnyJobRunningOrQueued.callCurrent(Unknown Source)
  10. at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
  11. at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
  12. at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:169)
  13. at Script1.run(Script1.groovy:48)
  14. at groovy.lang.GroovyShell.evaluate(GroovyShell.java:574)
  15. at groovy.lang.GroovyShell.evaluate(GroovyShell.java:612)
  16. at groovy.lang.GroovyShell.evaluate(GroovyShell.java:583)
  17. at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:442)
  18. at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:379)
  19. at hudson.plugins.groovy.SystemGroovy.run(SystemGroovy.java:95)
  20. at hudson.plugins.groovy.SystemGroovy.perform(SystemGroovy.java:59)
  21. at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
  22. at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:816)
  23. at hudson.model.Build$BuildExecution.build(Build.java:199)
  24. at hudson.model.Build$BuildExecution.doRun(Build.java:164)
  25. at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:524)
  26. at hudson.model.Run.execute(Run.java:1899)
  27. at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:44)
  28. at hudson.model.ResourceController.execute(ResourceController.java:107)
  29. at hudson.model.Executor.run(Executor.java:449)
  30. 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
}

  1. if (retries == maxRetries - 1) {
  2. println &quot;Max retries reached. Exiting...&quot;
  3. return
  4. }
  5. println &quot;Waiting for running and queued builds to complete...&quot;
  6. sleep(retryIntervalSec * 1000)
  7. 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 "-------------------------------------------------------------------------------------------------------------"

  1. def diskSpaceBeforeCleanup = runCommand(&quot;ls -ltrh /tmp | head -n 1&quot;)
  2. println &quot;TMP folder disk space before cleanup is $diskSpaceBeforeCleanup&quot;
  3. // runCommand(&quot;rm -rf /tmp/&lt;files&gt;&quot;)
  4. println &quot;-------------------------------------------------------------------------------------------------------------&quot;
  5. def diskSpaceAfterCleanup = runCommand(&quot;ls -ltrh /tmp | head -n 1&quot;)
  6. println &quot;TMP folder disk space after cleanup is $diskSpaceAfterCleanup&quot;
  7. println &quot;-------------------------------------------------------------------------------------------------------------&quot;

} else {
println "Skipping cleanup as other Jenkins jobs are running or queued."

  1. println &quot;Running builds:&quot;
  2. if (runningBuilds.isEmpty()) {
  3. println &quot;No running builds.&quot;
  4. } else {
  5. println runningBuilds.join(&#39;\n&#39;)
  6. }
  7. println &quot;Queued builds:&quot;
  8. if (queuedBuilds.isEmpty()) {
  9. println &quot;No queued builds.&quot;
  10. } else {
  11. println queuedBuilds.join(&#39;\n&#39;)
  12. }

}

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
}
}
}

  1. // Check queued builds
  2. if (queue.items.size() &gt; 0) {
  3. return true
  4. }
  5. return false

}

  1. Tried using Jenkins.instance instead of hudson and removed manager as well
  2. def jenkins = Jenkins.instance
  3. def queue = jenkins.queue
  4. and this-
  5. def queue = Jenkins.instance.queue
  6. But I still see errors
  7. groovy.lang.MissingPropertyException: No such property: Jenkins for class: Script1
  8. at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:66)
  9. at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:51)
  10. at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:310)
  11. at Script1.run(Script1.groovy:6)
  12. </details>
  13. # 答案1
  14. **得分**: 1
  15. 这段代码的一部分看起来有问题:
  16. ```groovy
  17. def isAnyJobRunningOrQueued(queue) {
  18. // 检查所有计算机上运行的构建
  19. for (computer in manager.computers) {

你在方法中使用了脚本变量 manager,但没有将其作为参数传递。你可以尝试将其改成如下所示:

  1. def isAnyJobRunningOrQueued(queue, manager) {
  2. // 检查所有计算机上运行的构建
  3. for (computer in manager.computers) {

并且修改 isAnyJobRunningOrQueued 方法的调用:

  1. if (!isAnyJobRunningOrQueued(queueAfterWait, manager)) {

希望这对你有所帮助。

更新:
另一种选项是将 manager 声明为全局变量,而不是 def manager = bla-bla。以下是一个小的测试脚本,以便你了解 Groovy 中局部变量和全局变量的工作方式:

  1. def scriptVar = '我是局部变量'
  2. globalVar = '我是全局变量!'
  3. someMethod()
  4. def someMethod() {
  5. // println "scriptVar = $scriptVar" -- 这将失败!!!
  6. println "globalVar = $globalVar"
  7. }
英文:

To me this part of code looks suspicious:

  1. def isAnyJobRunningOrQueued(queue) {
  2. // Check running builds on all computers
  3. for (computer in manager.computers) {
  4. ----------

You're using script variable manager in the method without passing it as a parameter. Could you try to change it to:

  1. def isAnyJobRunningOrQueued(queue, manager) {
  2. // Check running builds on all computers
  3. for (computer in manager.computers) {
  4. ----------

and change the call of the isAnyJobRunningOrQueued method:

  1. if (!isAnyJobRunningOrQueued(queueAfterWait, manager)) {
  2. -------

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:

  1. def scriptVar = &#39;I am local&#39;
  2. globalVar = &quot;I&#39;m global!&quot;
  3. someMethod()
  4. def someMethod() {
  5. // println &quot;scriptVar = $scriptVar&quot; -- it fails!!!
  6. println &quot;globalVar = $globalVar&quot;
  7. }

huangapple
  • 本文由 发表于 2023年8月10日 10:32:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76872311.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定