Thread.currentThread().executable doesn't work with pipeline jobs

2,049 views
Skip to first unread message

Jimilian

unread,
Aug 23, 2016, 5:59:27 AM8/23/16
to Jenkins Developers
Hi!

My team started to convert jobs from Freestyle jobs to Pipeline jobs, and we figured out that `Thread.currentThread().executable` doesn't work anymore.
What's best replacement for this?

Br, Alex

Daniel Beck

unread,
Aug 23, 2016, 6:14:02 AM8/23/16
to jenkin...@googlegroups.com
currentBuild, mostly.

See the /pipeline-syntax/globals URL on your Jenkins.
> --
> You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/637b921d-a6e8-49ef-be84-876e54b0b1e7%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Jimilian

unread,
Aug 23, 2016, 7:20:44 AM8/23/16
to Jenkins Developers, m...@beckweb.net
"currentBuild" doesn't work too.
I forgot to add that we are using Groovy Event Listener Plugin to publish data. So, this script is executed in 'onFinalized' method.

>>> Caught unhandled exception! No such property: currentBuild for class: script1471951099891369958697
groovy.lang.MissingPropertyException: No such property: currentBuild for class: script1471951099891369958697
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50)
	at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:231)
	at script1471951099891369958697.run(script1471951099891369958697.groovy:9)
	at script1471951099891369958697$run.call(Unknown Source)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl.runScript(GlobalEventsPlugin.groovy:305)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl.this$3$runScript(GlobalEventsPlugin.groovy)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl$this$3$runScript.callCurrent(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl$this$3$runScript.callCurrent(Unknown Source)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl.safeExecGroovyCode(GlobalEventsPlugin.groovy:275)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl.this$3$safeExecGroovyCode(GlobalEventsPlugin.groovy)
	at sun.reflect.GeneratedMethodAccessor195.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:231)
	at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:52)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl.safeExecGroovyCode(GlobalEventsPlugin.groovy)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl.this$3$safeExecGroovyCode(GlobalEventsPlugin.groovy)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl$this$3$safeExecGroovyCode.callCurrent(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl$this$3$safeExecGroovyCode.callCurrent(Unknown Source)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalEventsPlugin$DescriptorImpl.processEvent(GlobalEventsPlugin.groovy:219)
	at org.jenkinsci.plugins.globalEventsPlugin.GlobalRunListener.onFinalized(GlobalRunListener.java:54)
	at hudson.model.listeners.RunListener.fireFinalized(RunListener.java:232)
	at hudson.model.Run.onEndBuilding(Run.java:1893)
	at org.jenkinsci.plugins.workflow.job.WorkflowRun.finish(WorkflowRun.java:522)
	at org.jenkinsci.plugins.workflow.job.WorkflowRun.access$1000(WorkflowRun.java:107)
	at org.jenkinsci.plugins.workflow.job.WorkflowRun$GraphL.onNewHead(WorkflowRun.java:759)
	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.notifyListeners(CpsFlowExecution.java:799)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$4.run(CpsThreadGroup.java:320)
	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$1.run(CpsVmExecutorService.java:32)
	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:471)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)

Jesse Glick

unread,
Aug 23, 2016, 4:28:34 PM8/23/16
to Jenkins Dev
On Tue, Aug 23, 2016 at 7:20 AM, Jimilian <mr.ak...@gmail.com> wrote:
> I forgot to add that we are using Groovy Event Listener Plugin to publish
> data. So, this script is executed in 'onFinalized' method.

So patch that plugin to actually take the `Run` it received in
`onFinalized` and make it available to the script.

Jimilian

unread,
Aug 24, 2016, 2:50:52 AM8/24/16
to Jenkins Developers
Fortunately, it's already there.
Unfortunately, I can't trust to this 'Run', that's why we used `Thread.currentThread().executable`.

Why it's impossible to trust:
* Our master is pretty highloaded (several jobs can be finilazed in same moment, from 90k-120k executions per day)
* To avoid script compilation every time plugin shares Script object between different threads/builds.
* groovyScript.setBinding(new Binding(params)) is not thread-safe

If I understood Daniel correctly, `currentBuild` should be available? But, maybe, only from different class loader?
Can I patch Jenkins to provide similar to Thread.currentThread().executable behaviour for pipeline jobs as well?

p.s. I know that I can avoid shared state in plugin by compiling script every time, but I don't do that as well, because we are trying to reduce memory usage as much as possible.

Daniel Beck

unread,
Aug 24, 2016, 5:40:47 AM8/24/16
to jenkin...@googlegroups.com

> On 24.08.2016, at 08:50, Jimilian <mr.ak...@gmail.com> wrote:
>
> If I understood Daniel correctly, `currentBuild` should be available? But, maybe, only from different class loader?
>

I misunderstood what you're doing, since you mentioned Pipeline I assumed you were working inside the Pipeline DSL.

Jesse Glick

unread,
Aug 25, 2016, 7:09:24 AM8/25/16
to Jenkins Dev

Then there is a bug in the plugin. It should use `ThreadLocal` or similar to ensure that a given `Script` is only used for one build at a time.

Reply all
Reply to author
Forward
0 new messages