JavaScript on Rhino on Java on App Engine
I've got a limited amount of free time, and there's a lot of stuff in this world to play around with. When I'm trying to put together little demos and things, I tend to use Python on the server side -- it's a succinct, loosely type language with a lot of time and typing-saving features. Also, it's an interpreted language; App Engine's development server automatically catches change you make to a file, so my development cycle is just type-save-reload (leaving little time for swordplay).
Some of those language features' advantages start not to be advantages when your app gets more complex, however. When writing a large application, features like type checking, interface definition, and member access permissions become essential. While they introduce a lot of verbosity, they do make the problem of writing a large, complex, and (hopefully) fast app easier.
It's little surprise, then, that the second runtime the App Engine team released is Java (sadly, not Fortran).
For certain tasks, I'll even admit I like Java. It has its time and place. But what gets me excited about the App Engine announcement is that there are a lot of scripting language implementations that are written for Java. Two that should get web folks excited are JRuby and, for JavaScript, Rhino.
I'm excited about the latter. Rhino on App Engine means that I can quickly script apps in probably my most productive language, JavaScript. So I took some time yesterday mashing up the embedded Rhino examples with App Engine's "Hello World!" example.
The two classes, hopefully in a working state, are here, sans all the import statements:
Basically, I'm just exposing to the JavaScript environment an object, in the global scope, named "request" with one method: "write". Obviously, as a more robust framework, you could expose more of the underlying App Engine APIs, or even make the Java objects available for scripting.
Anyway, in this way, you can start writing your server side logic in JavaScript. So in this example,
Cool stuff. This is really the first I've ever worked with Rhino, but I hope to spend some more of my free cycles on this and come up with a more general system for working server-side in JavaScript on App Engine. There's a lot of potential here.
Some of those language features' advantages start not to be advantages when your app gets more complex, however. When writing a large application, features like type checking, interface definition, and member access permissions become essential. While they introduce a lot of verbosity, they do make the problem of writing a large, complex, and (hopefully) fast app easier.
It's little surprise, then, that the second runtime the App Engine team released is Java (sadly, not Fortran).
For certain tasks, I'll even admit I like Java. It has its time and place. But what gets me excited about the App Engine announcement is that there are a lot of scripting language implementations that are written for Java. Two that should get web folks excited are JRuby and, for JavaScript, Rhino.
I'm excited about the latter. Rhino on App Engine means that I can quickly script apps in probably my most productive language, JavaScript. So I took some time yesterday mashing up the embedded Rhino examples with App Engine's "Hello World!" example.
The two classes, hopefully in a working state, are here, sans all the import statements:
public class Response extends ScriptableObject {
public Response() {
out = new StringWriter();
}
@Override
public String getClassName() { return "Response"; }
public void jsFunction_write(String str) {
out.write(str);
}
public StringWriter out;
}
public class RhinoServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException {
res.setContentType("text/plain");
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
ScriptableObject.defineClass(scope, Response.class);
Scriptable response = cx.newObject(scope, "Response");
ScriptableObject.putProperty(scope, "response", response);
FileReader reader = new FileReader("hellorhino.js");
Object result = cx.evaluateReader(scope, reader, path, 1, null);
Response javaResponse = (Response) cx.jsToJava(
response, Response.class);
res.getWriter().write(javaResponse.out.toString());
} catch (Exception ex) {
res.setStatus(500);
res.getWriter().println(ex.toString());
} finally {
Context.exit();
}
}
}
Basically, I'm just exposing to the JavaScript environment an object, in the global scope, named "request" with one method: "write". Obviously, as a more robust framework, you could expose more of the underlying App Engine APIs, or even make the Java objects available for scripting.
Anyway, in this way, you can start writing your server side logic in JavaScript. So in this example,
hellorhino.js is just:
var words = ['Hello', 'World!'];
response.write(words.join(' '));Cool stuff. This is really the first I've ever worked with Rhino, but I hope to spend some more of my free cycles on this and come up with a more general system for working server-side in JavaScript on App Engine. There's a lot of potential here.