[ 
https://issues.apache.org/jira/browse/GROOVY-7407?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jex Jexler updated GROOVY-7407:
-------------------------------
    Attachment: WorkaroundGroovy7407WrappingGrapeEngine.java

I wrote a workaround that may be useful in some situations, the Java source is 
attached in {{WorkaroundGroovy7407WrappingGrapeEngine.java}}.
{code}
/**
 * A GrapeEngine that wraps the current GrapeEngine with a wrapper where all 
calls
 * of the GrapeEngine API are synchronized with a configurable lock, and allows 
to
 * set this engine in the Grape class.
 *
 * Works at least in basic situations with Groovy 2.4.3 where the wrapped 
GrapeEngine
 * is always a GrapeIvy instance (not all public interface methods have been 
tested).
 *
 * But note that while a synchronized GrapeEngine call is in progress (which 
may take
 * a long time to complete, if e.g. downloading a JAR file from a maven repo),
 * all other threads that want to pull Grape dependencies must wait...
 *
 * Several things are not so nice about this approach:
 * - This is using a "trick" to set the static protected GrapeEngine instance 
in Grape;
 *   although nominally protected variables are part of the public API (and in 
this case
 *   is shown in the online JavaDoc of the Grape class).
 * - The "magic" with "calleeDepth" is based on exact knowledge of what GrapeIvy
 *   does (which, by the way, appears even inconsistent internally(?)), so this
 *   workaround is not guaranteed to be robust if GroovyIvy implementation 
changes.
 * - I refrained from referring to the GrapeIvy class in the source, because it 
is
 *   not publicly documented in the online JavaDoc of groovy-core.
 */
{code}
To use the workaround, call 
{{WorkaroundGroovy7407WrappingGrapeEngine.createAndSet();}} somewhere early. 
The two previously attached unit tests pass if this is done.

> 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
>            Assignee: Paul King
>            Priority: Minor
>              Labels: Compile, Grape, Groovy, Ivy
>         Attachments: GrapeAndGroovyShellConcurrencyTest.java, 
> GroovyCompileConcurrencyTest.java, 
> WorkaroundGroovy7407WrappingGrapeEngine.java, 
> stacktrace-GrapeAndGroovyShellConcurrencyTest-1.txt, 
> stacktrace-GrapeAndGroovyShellConcurrencyTest-2.txt, 
> stacktrace-GroovyCompileConcurrencyTest-1.txt, 
> stacktrace-GroovyCompileConcurrencyTest-2.txt
>
>
> 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
(v6.3.4#6332)

Reply via email to