[jira] [Commented] (GROOVY-7407) Compilation not thread safe if Grape / Ivy is used in Groovy scripts

Previous Topic Next Topic
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

[jira] [Commented] (GROOVY-7407) Compilation not thread safe if Grape / Ivy is used in Groovy scripts

JIRA jira@apache.org

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

Jex Jexler commented on GROOVY-7407:

I tried to see if locking "per artifact" (group:module:version) could be a solution, using the following code in GrapeIvy to lock on grab() and resolve():
    private Map<String,Object> lockMap = new HashMap<>()
    private Object getLock(Map... dependencies) {
        String group
        String module
        String version
        for (Map dep : dependencies) {
            if (dep.group != null) {
                group = dep.group
            if (dep.module != null) {
                module = dep.module
            if (dep.version != null) {
                version = dep.version
        String key = "$group:$module:$version"
        synchronized (lockMap) {
            Object obj = lockMap.get(key)
            if (obj == null) {
                obj = new Object()
                lockMap.put(key, obj)
            return obj
    public grab(Map args, Map... dependencies) {
        synchronized (getLock(dependencies)) {

but this did not help with a modified version of GroovyCompileConcurrencyTest in which one in 10 compilation units used guava versions 10,11,12, ...19.
So whatever the issue is, locking on the GrapeEngine interface level per artifact would apparently not to be a viable approach.

> Compilation not thread safe if Grape / Ivy is used in Groovy scripts
> --------------------------------------------------------------------
>                 Key: GROOVY-7407
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7407
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler, Grape
>    Affects Versions: 2.4.3
>         Environment: Essentially independent of the environment, as long as Groovy scripts use Grape; also this bug seems to be present since at least Groovy 1.7.5.
>            Reporter: Jex Jexler
>            Priority: Minor
>              Labels: Compile, Grape, Groovy, Ivy
>         Attachments: GrapeAndGroovyShellConcurrencyTest.java, GroovyCompileConcurrencyTest.java, stacktrace-GrapeAndGroovyShellConcurrencyTest-1.txt, stacktrace-GrapeAndGroovyShellConcurrencyTest-2.txt, stacktrace-GroovyCompileConcurrencyTest-1.txt, stacktrace-GroovyCompileConcurrencyTest-2.txt, WorkaroundGroovy7407WrappingGrapeEngine.java
> If Groovy scripts that import the same libraries via Grape are compiled in separate threads, compilation may fail due to race conditions.
> This does not happen if several threads use the *same* instance of GroovyClassLoader (GCL), because parseClass() uses synchronization.
> But as soon as different GCLs are used in separate threads or if the compiler is used directly (CompilationUnit.compile()), the issue occurs and compilation can fail.
> Two Java unit tests have be attached, which reproduce the issue, although this cannot be guaranteed with 100% certainty, because there is a race condition.
> Two different stacktraces have been observed for each unit test (with origins in Grape and in Ivy), which have also been attached (plus in a different environment (Tomcat webapp CentOS) once a an exception down in Ivy had been observed that seemed to be related to unzipping a JAR file, but no precise record of that exists any more).

This message was sent by Atlassian JIRA