Server-Side JavaScript with Rhino and Jetty

I'd like to write server-side code in JavaScript. It just makes good sense. Developers that know JavaScript well are likely not doing much work with servers. All those ports and stuff. I'll take browser bugs instead any day :) Anyway the recent word that Steve Yegge wrote a Rhino on Rails (porting most of Rails to JavaScript) prompted me to look into this further.

The example included in this post is the front end of a server-side framework for writing apps in JavaScript. I used the Rhino JavaScript engine from Mozilla and a pure Java web server called Jetty. Both Rhino and Jetty are used in the long-lived Helma project for server-side JavaScript.

The idea was to send all requests to a single JavaScript function. That is essentially what happens in Rails: everything goes to one dispatcher file. Then the request goes to routing where the URL is inspected and the appropriate controller/action pair is chosen to process the request.

After reading some Rhino, Jetty and Helma examples and source code, I've produced a simple example. You can download the example (1.4 MB including Rhino and Jetty) and try for yourself. Read the README.txt. As long as you have a Java Virtual Machine on your computer (which your Mac does) then you just type the following inside the harmony directory

./server

and look at http://localhost:3000/ to see a congratulations page. That's it. It couldn't get easier. Ahh the success of yet another "hello world".

Talking to a database from inside this example is the other critical step in creating a simple web app framework. That's next.

Update July 11, 2007: In a follow up article added the database into the mix for the full meal deal.

Update October 26, 2007: I completely rewrote the example for this article. The original example code was based on an example from Chris Double's blog which describes how to start Jetty from within the JavaScript running in the Rhino shell. I think this architecture was a bit inside out and would have servlet threading issues. If you are really curious you can download the original example (1.2 MB including Rhino and Jetty).

Comments

Have something to write? Comment on this article.

Jonas August 10, 2007

Hey Peter!

I am not that JS-"pro", as you are... I know how to program js,python,php,etc. but I have never ever heard of running server side JavaScript. I understand that this is possible with your Jetty and Rhino-Tricks, but why does is make sense to push get requests to a JavaScript function? Why not use php? i am confused

... i will do a little research ;P

Greetz,
J

Peter Michaux August 11, 2007

Jonas,

You could use any of PHP, Perl, Python, Ruby, Lisp, Java, C, etc to generate the response to a GET request. Which of these languages you choose is personal preference based on which language you see being best for the task at hand. There are many developers that see the benefit of writing both client-side and server-side code in the same language. JavaScript is the language in the browser so there is a natural argument that leads to using JavaScript on the server-side also.

In this examples I send all GET requests to a single JavaScript function on the server which acts as a "front door" to the server-side JavaScript application. I know this is how Ruby on Rails operates. Having the server-side scripting language take over processing the request as soon as possible (rather than having apache route the request) means that the script programmer has control early instead of the web-server administrator.

SimoneGianni September 22, 2007

Hi Peter,

have you ever looked at Apache Cocoon flowscript system? It is basically a way to write web applications, server side, in javascript. Using also a lot of nice features like continuations and having the strong power of a complete java xml framework.

Simone

Peter Michaux September 23, 2007

Simone,

I haven't looked at Cocoon in great depth. XML is not my thing. I'm looking for a JavaScript server-side framework written completely in JavaScript. Even JSON for config files. This way everything is potentially sharable with the client. Trimpath exploits this idea.

I like some if the ideas of Helma. I like the "object publishing" concept but the Helma framework is written in Java.

Fortunately I have a bit of time on my hands and have some time to play with writing my own framework based on some ideas in this blog post.

Chris October 24, 2007

I cannot get this to work on my mac for some reason. I've tried all sorts of things like downloading the latest version of jetty, xbean, etc. Any possible hints?

Peter Michaux October 27, 2007

Chris,

Not sure why the old example didn't work for you. I just uploaded a completely rewritten example. Please give it a try if you are interested.

Chris Anderson October 27, 2007

I played around with writing a Rails-like routing system. Javascript lends itself really well to DSLs (as long as you don't mind the syntax) so it looks like it could turn out well. Here's how you interact with it so far. I'd like to add resources() as a macro to define the conventional RESTful actions, but this is a start.

connect('/info/show', controllers.info.show);
connect('/',          controllers.front.index);

The code that supports it just barely works, so it's not worth posting yet. If Harmony had two little changes it would make development so much smoother. 1) A "development" mode where the app.js file is reloaded for each request. 2) print errors to the browser so I don't have to juggle 3 windows.

I managed to hack my way toward these goals, just added

shell.loadFile("app.js");

to the top of processRequest() and did a try..catch around

shell.callGlobalFunction("app", args);

The behaviour is pretty rough but it sure is fun to hack in a lightweight server-side Javascript environment.

Peter Michaux October 27, 2007

The code in this example is bare bones. I have a more developed version of Harmony on my computer. The shell is more complete with FILE macro like C and Ruby have so one file can load others with relative paths to promote modularity. It has development modes and environment config files like Rails does. It does the automatic reload in development mode. I'm still working on how to organize the framework files and the various database adapters. The ORM is the biggest huddle I think. Various deployment strategies also need consideration. It is fun to play with this stuff before it turns into a big framework with twenty thousand lines of code but it really does require a lot of work to get to a stage where it could be used for a real project.

Chris Anderson October 29, 2007

Peter,

If you're up for sharing the more developed version of Harmony, I'd love to play around with it. I've been having second thoughts about building a Rails clone in JS.

I'm interested in making the smallest atom of behavior a resource, each of which responds to GET PUT POST and DELETE. Simplifies the routing problem as well as encouraging best practices. IBM's Project Zero has a similar architecture written in PHP.

I'm still not sure how far one can get while maintaining a direct correspondence between the model layer and the URI namespace, but if it works out it seems like a big boon for simplicity.

Peter Michaux October 29, 2007

The code I'm working on is not ready for public viewing yet. It is still chaotic and very experimental.

I'm doing almost exactly what you suggest with each resource reflected as a URL with REST actions. It isn't MVC in the same way Rails is but there is still separation of the various kinds of code. I think this is a good thing as even Rails now seems repetitive and laborious. It is hard to have imagined writing that when Rails was first released.

Chris December 18, 2007

Peter,

I've been playing with your setup and ran into an issue.

For some reason, I'm not able to access certain functions such as readFile from within the app() function.

Probably due to my inexperience with java, but everything I've tried won't work.

Any insight into the problem would be helpful!

Gemblon January 9, 2008

is there examples for setting up on Vista? or do i need to boot up fedora or debian?

- thanks

Peter Michaux January 12, 2008

Gembion, these directions are for Mac OS X and I think would work on Linux quite easily. I don't know about Windows.

Have something to write? Comment on this article.