[
https://issues.apache.org/jira/browse/GROOVY-11775?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18038482#comment-18038482
]
Björn Kautler commented on GROOVY-11775:
----------------------------------------
> When you mix in SpecialMethodCallTarget to Specification, you are calling it
> repeatedly. I'm not sure if it is once per test or once per thread.
Argh, oh, my, you are totally right, stupid me.
I intentionally did it in
{{org.spockframework.runtime.SpockEngineDescriptor#prepare}} as that should
only run once before all Spock tests get executed, only if maybe a worker
process is reused to run Spock tests again it would rerun,
not because I thought it might make problems, but simply because I wanted to
avoid unnecessary work.
Now the problem is that I was running Spock's own tests.
There are quite some {{EmbeddedSpecRunner}} usages to test Spock itself.
And for those each time a {{SpockEngineDescriptor}} is of course created and
prepared, so the mixing in is done again.
And additionally, the tests are of course configured to run in parallel.
So after the first two lines in my {{FOO: ...}} result above,
most probably another embedded spec runner test was started in parallel and did
the {{mixin}} call.
The metamethods from the new call replaced the metamethods from the previous
call.
Then the next line of the {{FOO: ...}} result above was executed, working with
a fresh instance of the newly mixed in class, causing said effects.
!StarTrekPatrickStewartGIF.gif!
For stateless mixins this is not a problem at all.
But to use the mixin approach with state, I should have checked whether the
mixin is already mixed in and only mix it in if not, then it should probably
have prevented the problem too,
basically what you did in Groovy itself now if I got it right.
Thanks for looking into this and hopefully fixing it, even though I anyway
chose a different approach at last. :-)
> Stateful runtime mixins sometimes do not work properly
> ------------------------------------------------------
>
> Key: GROOVY-11775
> URL: https://issues.apache.org/jira/browse/GROOVY-11775
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 4.0.26
> Reporter: Björn Kautler
> Assignee: Eric Milles
> Priority: Major
> Attachments: StarTrekPatrickStewartGIF.gif
>
>
> I have class {{A}} and class {{B}}.
> I {{mixin}} {{A}} to {{B}} using {{B.mixin(A)}}.
> {{A}} has a property {{X}}.
> Now I have a method {{M}} in a subclass of {{B}} which first calls a method
> {{N}} of {{A}}, then another method {{O}} of {{A}}.
> Both calls happen linearly, both happen on the same thread, yet occasionally
> the call to {{O}} hits a different instance of {{A}} than the call to {{N}}
> and thus {{N}} and {{O}} work on a different instance of the field in {{A}}.
> From a quick look at the code and debug, the problem might maybe be, that the
> {{MixinInMetaClass#managedIdentityConcurrentMap}} holds the {{B}} instances
> that serve as key in soft references. So maybe if the heap gets exhausted
> between calling {{N}} and {{O}}, the map entry is nuked by the garbage
> collector and thus the {{O}} call creates a new {{A}} instance.
> If this is the case (or actually whatever else causes what I see), stateful
> runtime mixins are quite flaky and should not be used unless this is fixed,
> as you cannot rely on the state. Actually, I was not able to knit an MCVE by
> intentionally triggering two OOME between the calls to {{N}} and {{O}}, so my
> suspicion about the cause might not be correct.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)