I spotted this while going through the code of Camunda Engine. In ExpressionManager, there is piece of code following a famous pattern for lazy initialization:
In short: elResolver is not volatile.
More details: What could happen is that elResolver can be not fully initialized when read by other threads. Of course, such issue is difficult to detect, especially because most of servers run with x86 CPUs that have a TSO memory model so it cannot happen but can occur with other architectures (e.g PowerPC).
Solution: make it volatile. More information about this kind of issue https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
I can raise a PR for that one if needed.