groovy-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Björn Kautler (JIRA) <j...@apache.org>
Subject [jira] [Comment Edited] (GROOVY-8213) Closures are maybe not Threadsafe
Date Mon, 12 Aug 2019 09:20:00 GMT

    [ https://issues.apache.org/jira/browse/GROOVY-8213?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16901218#comment-16901218
] 

Björn Kautler edited comment on GROOVY-8213 at 8/12/19 9:19 AM:
----------------------------------------------------------------

Actually I now tried to revert my work-around with Gradle 4.10.3 and now it even failed locally,
not only on CI with two out of two tries so far,
so this issue needs to be reopened, it is not fixed.


was (Author: vampire):
Actually I now tried to revert my work-around and now it even failed locally, not only on
CI with two out of two tries so far,
so this issue needs to be reopened, it is not fixed.

> Closures are maybe not Threadsafe
> ---------------------------------
>
>                 Key: GROOVY-8213
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8213
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.4.10
>         Environment: Gradle 3.5
>            Reporter: Björn Kautler
>            Assignee: John Wagenleitner
>            Priority: Major
>             Fix For: 2.4.13
>
>
> I just upgraded our Gradle build from 1.12 (including Groovy 1.8.6) to 3.5 (including
Groovy 2.4.10).
> Now I get a very strange behavior for stuff that is there for years already and it looks
to me as if this is a Groovy bug, maybe a non-threadsafeness of Closures.
> I have a custom task that contains the following code:
> {code}
>       def sourceFilesSize = getSourceFiles().files.size()
>       def poolSize = Runtime.runtime.availableProcessors()
>       def executor = new ThreadPoolExecutor(poolSize, poolSize, 0, SECONDS, new ArrayBlockingQueue<Runnable>([sourceFilesSize,
1].max()))
>       def tasks = []
>       inputs.outOfDate { toTransform ->
>          tasks.add executor.submit {
>             project.exec {
>                if (gscPath) { // here starts com.empic.build.tasks.Ghostscript$_exec_closure8$_closure11
>                   environment 'GSC', gscPath
>                   def tempDir = "$temporaryDir/${Thread.currentThread().name}"
>                   project.file(tempDir).mkdirs()
>                   environment 'TEMP', tempDir
>                }
>                executable executablePath
>                def arguments = [toTransform.file.absolutePath]
>                if ((sourceFilesSize == 1) && getDestinationFile()) {
>                   arguments << getDestinationFile().absolutePath
>                } else if (destinationDirectory) {
>                   arguments << new File(destinationDirectory, fileNameMapping(toTransform.file.name)).absolutePath
>                } else {
>                   arguments << new File(toTransform.file.parentFile, fileNameMapping(toTransform.file.name)).absolutePath
>                }
>                args arguments // here ends com.empic.build.tasks.Ghostscript$_exec_closure8$_closure11
>             }
>          }
>       }
>       executor.shutdown()
>       executor.awaitTermination 1, HOURS
>       tasks*.get() // here is line 137
> {code}
> When this task is executed e. g. with five source files, sometimes all works fine, sometime
the build fails with
> {noformat}
> ...
> Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalStateException:
initialize must be called for meta class of class com.empic.build.tasks.Ghostscript$_exec_closure8$_closure11(class
org.codehaus.groovy.runtime.metaclass.ClosureMetaClass) to complete initialisation process
before any invocation or field/property access can be done
>         at com.empic.build.tasks.Ghostscript.exec(Ghostscript.groovy:137)
>         at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
>         ... 80 more
> Caused by: java.lang.IllegalStateException: initialize must be called for meta class
of class com.empic.build.tasks.Ghostscript$_exec_closure8$_closure11(class org.codehaus.groovy.runtime.metaclass.ClosureMetaClass)
to complete initialisation process before any invocation or field/property access can be done
> {noformat}
> Actually I was not able to reproduce the problem locally, but if I run the build on our
CI server and attach a debugger, I indeed was able to reproduce the problem with a relatively
high reproduction rate. (as in every second to third build approximately, opposed to once
every 100 builds)
> I logged the current thread when the {{initialized}} property is set to {{true}} and
when it is requested with non-suspending breakpoints, but this seems to have caused the timing
to change enough already that I was not able to reproduce the error within approximately the
first two dozens of tries.
> I was able to successfully break at the throwing of the {{IllegalStateException}} though.
This happens in {{groovy.lang.MetaClassImpl.checkInitalised}}.
> The stacktrace at this point is:
> {noformat}
> "pool-2-thread-3@10709" prio=5 tid=0x47 nid=NA runnable
>   java.lang.Thread.State: RUNNABLE
> 	  at groovy.lang.MetaClassImpl.checkInitalised(MetaClassImpl.java:1647)
> 	  at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:257)
> 	  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
> 	  at groovy.lang.Closure.call(Closure.java:414)
> 	  at groovy.lang.Closure.call(Closure.java:408)
> 	  at groovy.lang.Closure.run(Closure.java:495)
> 	  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
> 	  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
> 	  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
> 	  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
> 	  at java.lang.Thread.run(Thread.java:745)
> {noformat}
> with the closure for which we are at the {{ClosureMetaClass}} in the topmost frame being
the mentioned {{com.empic.build.tasks.Ghostscript$_exec_closure8$_closure11}}.



--
This message was sent by Atlassian JIRA
(v7.6.14#76016)

Mime
View raw message