Details
-
Bug Report
-
Resolution: Unresolved
-
L3 - Default
-
None
-
None
-
None
Description
Example process, see test case: link
Context Explanation
- When compiling a Groovy script (which is default), the compiled script references an instance of org.jruby.embed.ScriptingContainer. This is a container for global variables.
- This container is created per scripting engine
- Every script compiled with the same scripting engine uses the same scripting container
- By default, Ruby scripting engines are cached
- Whenever a Ruby script is evaluated, the following steps happen (confer org.jruby.embed.jsr223.Utils and its methods preEval and postEval and where they are called; based on JRuby 9.1.17.0):
- Iterate the script bindings and dump the key value pairs into the scripting container
- Evaluate the script (possibly updating the scripting container if it defines new global variables)
- Iterate the scripting container and put all variables back into the script bindings (with autostoring variables, this proagates into the execution variable scope)
- Global variables from the scripting container can be accessed in a script via $<varname> syntax
Problem Explanation
- When we evaluate the Ruby environment script (defining the S function from Spin), then the same pre/post eval procedure happens
- The script bindings return the current execution, as well as all process variables
- The variables have leaked into the scripting container
- When a subsequent script is executed in the context of the same scripting container, then the variables are available as global variables, can be referenced, and if auto-storing is enabled, then they leak into the context execution (which might be in an entirely different process)
- Parallel execution of the same scripts overwrite each other's global variables (i.e. $<varname> may resolve to a value of another process instance)
Workaround Ideas
- Disable script engine caching
- This is only a partial workaround. It is only sufficient when autostoring is disabled.
- This is only a partial workaround. When the environment script is compiled, it happens in the context of a script task, so the task's actual script is compiled with the same engine, even if caching is deactivated. Since the environment script is executed with every script task, any execution will leak variables into its scripting container. The container is then shared with the script task that triggered environment script compilation, so variables can still leak into that script.
- Maybe there is a JRuby setting to change how global variables are treated