Mar 15, 2011 22:43
Okay. Lately, I've wanted to do a quick-n-dirty calculation program to allow users to enter mathematical formulae into a Java program and have it execute. As much as I wanted to implement a stack and do all that fun PEMDAS stuff, I decided to do a big of Bing-ing first. I found that you can write functions in JavaScript and have them executed using a ScriptEngine. Naturally, I wrote a very quick hundred-line test harness that took data in from a Swing form and chucked it through the ScriptEngine. The important code looks something like this:
import javax.script.*;
//...
String inputText;
//...
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
//...
engine.eval(inputText);
//...
Anyway, it does more than just math-type stuff. In JavaScript, you can use the importPackage() function to import Java stuff! So into this test harness, I typed the very first thing that any sane computer scientist would do:
importPackage(javax.script);
My harness didn't choke on it. So, naturally:
var engine = new ScriptEngineManager().getEngineByName("js");
Still no choking...
engine.eval( "engine2 = new ScriptEngineManager().getEngineByName(\"js\");" );
Further playing reveals creating an empty window using the script engine inside the script engine:
engine.eval( "engine2.eval(\" x = new JFrame() \")" );
engine.eval( "engine2.eval(\"x.setVisible(true);\")" );
So, what does this do? Essentially, Java allows infinite nesting of JavaScript environments inside Java. Now, why they wouldn't allow a Java environment inside of Java, I can't imagine. Admittedly, the purpose of this technology is so a developer could make their own scripting language on the fly; however, this is much more fun. Additionally, you can dynamically program in Java through JavaScript (through Java, through JavaScript ad infinitum) using other regular Java classes. That's right. If I were careful enough and had the patience, I could re-create my test-harness inside my test harness.
It's interesting to note that exception handling looks pretty interesting in this environment-in-an-environment situation.
I'm not too sure what practical use I'm going to put this to, yet, but there's ways to put, set, and get data from one of these environments, so it's quite open to exploitation.