Hi there,
my application contains some ASTTs which need to be applied to scripts which it
compiles. The code looks essentially like this (a bit simplified for better
readability; in practice there are try/catch harnesses, logs, expressions use
bindings, and such stuff):
===
@Lazy(soft=YES) static shell={
new GroovyShell(new GroovyClassLoader(),emptyBinding,cc)
}()
@Lazy(soft=YES) static compiledExpressionCache={
[:]
}()
static evaluate(String expression) {
def script=compiledExpressionCache[expression].get()
if (!script) {
script=shell.parse(expr)
compiledExpressionCache[expression]=new
java.lang.ref.SoftReference(script)
}
script.run()
}
===
Most time, it works excellently. Very very rarely -- just twice in many years
-- nevertheless a weird thing happened:
- the soft caches were cleared and re-created (in one case for the first, in
the other for 5th time)
- and **the newly created GroovyShell did not apply the ASTTs to subsequently
compiled expressions**!
Note during the application lifetime, the very same expressions were compiled
and used before (at least once; four times in the 2nd case), each time the
ASTTs were applied properly. Only with the last compilation they were not.
Do you have any idea what might have been the culprit? First time it happened
with Groovy 2.3.8, the second (and so far last) time with Groovy 2.4.21.
Of course, having found the problem, first thing I did was removing soft=YES
from the shell property, which should probably remove the problem (for a price
of a completely negligibly higher memory consumption; the only reason I did use
soft originally is I a habit to soft all caches :)) Nevertheless, I would still
like to understand what might have caused it.
I'll be grateful for any insight,
OC