It’s a very common situation when an application needs some runtime customization, but it’s impossible via settings and you are too lazy to change source code, or you just cannot update your application too often. In that case you may use different script engines in order to change application behavior in runtime. Moreover, the developer doesn’t have to do changes themself. It may be the duty of administrators, analysts, etc
So, I want to describe the way of one java application, from the simplest script engine up to engines with secured sandboxes.
- Access to Java classes
- Implement a sandbox
It’s a part of JDK and there is even a console interpreter.
jjs jjs> print (‘giggity’) giggity
Integration is also very simple:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); engine.eval("print('giggity');");
The next step – Groovy engine
Binding binding = new Binding(); GroovyShell shell = new GroovyShell(binding); Script scrpt = shell.parse(new File("app.groovy")); binding.setVariable("foo", "bar"); shell.evaluate("println(foo)")
So we had the full power of a Java Virtual Machine. Since that point our application was going to production usage. A little bit about the app – it contains a huge amount of very sensitive data. Also, there are complex ACLs, rules and so on, which are protecting data from unauthorized access. In this stage we were faced with big security issues. As I mentioned before, we had the full power of JVM and user-script had access to reflection API, internal classes, bean, processes and so on. The first thing that we tried was the sandbox by Kohsuke Kawaguchi. For the first try it was ok, but it works only as a whitelist model. It became incompatible with our requirements. In my next post I will describe how we’ve built sandbox for paranoid.