Hey, it's been awhile since I last posted on this blog, largely because I didn't have much to say about Java for awhile, and partly because I've been working with Node.js over the last year. It's a new software platform that I think the Java community needs to know about, and as the author of a book about Node (a.k.a. Node.js) I may be the person to explain a thing or two to y'all. Since it's been so long since my last post here, a bit of re-introduction should be useful. I'd spent 10 1/2 years working for Sun in the Java SE team, as an architect of the Software Quality Engineering team (SQE). I was also someone who had some interesting ideas to share about Java (hence this blog). Well, I hope they were interesting. During that time, I was privileged to meet the FreeJava community (classpath, harmony, etc), participating in launching the OpenJDK project, the JDK-Distros project, the Mustang Regressions contest, and some other interesting projects. It was an amazing time of meeting the broader Java community. But 2.5 yrs ago things changed (ahem) and I stopped being active with Java and didn't want to post here because I wasn't sure I had anything to say. Until now, when I feel a need to talk about Node.
Node (a.k.a. Node.js) is a new software development platform where the main talking points are:-
- Server-side JavaScript executing on a fast JavaScript virtual machine (Chrome's V8)
- Asynchronous execution model that's claimed to be light-weight and highly scalable
- A no-threads mantra that synergistically works with the asynchronous model to make each connection low cost for high scalability
- Excellent network I/O event handling event dispatching asynchronous runtime library that makes it amazing easy to develop succinctly implemented server software
- Growing ecosystem of add-on modules and web frameworks and more
- Excellent module system and package management system; cures dependency hell
Node's "hello world" is a 6 line script that also implements an HTTP web server.
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');
While most of the attention is on Node as a means to implement server applications, that's not all. It's a general purpose programming platform akin to the Perl or Python or Tcl or Java model of use. That is, you write your code and rather than compile it to object code it's run with an execution engine. The Node execution engine is Chrome's V8 virtual machine wrapped with the layers that make Node what it is - namely the core runtime packages which come baked into the executable.
Okay, great. What does that mean and how to contrast it with Java?
One thing that leapt to mind early on was the old dream of the same language on both client and server side. This dream perhaps dates back to the early days of Java, where Applets were to be how we'd implement dynamic stuff in a browser, and Servlets would be how we'd do it on the server. The same language on both client and server could/should/would/maybe give us some goodness. Who knows, but something in that dream failed along the way and we ended up with JavaScript in the browser and various languages on the server. With Node we have a new chance for this dream to occur, but this time the language is JavaScript and in the browser JavaScript+DOM and asynchronous requests have given us some amazing web experiences. Maybe we'll be able to write JavaScript code which could execute either in the browser or on the server depending on some conditions, or maybe not. But having the same language at both sides should make it easier for different implementation teams to communicate and work closely together.
I think an area where Node can shine extremely well is in implementing the real time web. Okay, sure, Twitter implemented their real time web with Ruby and Scala, but they started on that before Node existed. I base my thinking in part on some 2006 blog posts that led to the COMET protocol, and in part the architectural choices in the Node platform.
Those 2006 blog posts described problems with thread-based architectures when there are 10's of thousands of connections to a single web server. Why that many? Because the goal was for websites to be asynchronously popping messages onto screens and doing various other things which required holding a connection open to each web browser for a long time. Think Facebook and their ability to tell you that so-and-so liked something you posted earlier, that's implemented with a long running connection over which messages are sent.
In a thread-based system the overhead of one thread per connection means a server can't scale to very many connections, resource utilization is low and you're having to buy excess servers to get the job done, which cooks the planet because of too much electricity consumed to drive the Internet. The 2006 COMET blog posts described a different asynchronous architecture that removes overhead implementing the real time web more efficiently for better resource utilization. Okay, I hope I'm characterizing those posts correctly.
In any case those posts discuss implementing this in Java - Java's nio package lets you implement asynchronous I/O and Java is a powerful platform. It begs the question, why do I think Node is great for the real time web, and why didn't Node's authors (especially Ryan Dahl) use Java as its foundation rather than JavaScript.
I don't know why Ryan Dahl didn't do Node with Java but instead used V8. I did read all his blog posts and know he was really interested in high performance web service development along the lines of those COMET blog posts. He was also hot on "no threads" because threads incur memory/CPU/complexity overhead. What I can say is that JavaScript is highly suited to this task, in a way that Java is very clunky at.
What I mean is that closures (anonymous functions) come baked into JavaScript and are routinely used for event handling. I don't know diddly about the technical definition of closures, but can say that anonymous functions are quite fun to use for writing what's essentially a Listener function.
In Java implementing an event handler is done by defining a Listener interface class, then importing that interface, implementing a subclass of the interface, and filling in one or more functions with your business logic. Along the way you have to dot every i and cross every t with correct type signatures. Isn't it tiring just listening to how this is done?
In JavaScript an event handler is as simple as "function(arg, list) { code .. }" .. no muss .. no fuss .. quite easy and fun.
It's possible to rathole down a discussion of dynamic typing versus rigid static typing ... I don't want to go there. If you look in the back history of my blog posts on java.net I think you'll find me arguing the other side, that we have to have rigid static typing to help us steer clear of broken code. I can say that this dynamic coding methodology is a heck of a lot of fun, and wish my former "rigid static typing" self would just get over it.
Something that helps a lot is Node's excellent module system. Modules themselves are pretty straight-forward. The design was borrowed from CommonJS and implements a strong encapsulation around each module. The code that's internal to a module simply cannot be reached from outside the module, and you export explicitly the functions you want to expose.
What makes it excellent is the algorithm for finding modules. It's flexible enough that an application could have within its code tree several different versions of the same module, to allow fine grained dependency resolution.
Because HTTP is a built in core module it's amazingly simple to write REST-based server (or client) applications with Node. The "req" and "res" objects shown in the hello world above abstract the HTTP protocol conversation. All a service function does is fill in data in the res object, add data to the body, and that's it. The HTTP object takes care of serializing the data down to the HTTP protocol for you.
In my book, Node Web Development, I was able to demonstrate in 6 pages refactoring a web application to move a heavy computation to a back end server using a REST service. That 6 pages included a REST server, a small client application to test the back end server, and to refactor the application to use the REST server. Six pages. To me that demonstrates the power and flexibility of Node because of how easy it was to do all that.
This post has gotten a little long in the tooth, so I want to draw it to a close. I hope y'all found it useful. I've been working with Node for almost a year and the whole time in the back of my mind I was going on and on comparing back and forth between Java and Node and... Node is freeing JavaScript from being trapped in the browser, and letting it shine in a new place. Yes, I know about the largely unknown history of server-side-javascript, but SSJS has had very little impact on computing and JavaScript has become synonymous with client side programming. Node is the first serious outing of SSJS and it's a platform with great potential. If you want to follow my adventure with Node head over to Node.js Web Development.
Source: weblogs.java.net