I’ll Get You My Jetty, And Your Little Dog, Too!

Okay, maybe I’m the last person in the known universe to develop Jetty-love, but I’ve developed it, nonetheless.

For the last few years, my typical development environment for web projects has been pretty consistent. I use Eclipse and MyEclipse to write my code (Java, HTML-like stuff, CSS, etc.). And I usually have JBoss installed on my development machine to deploy stuff to a server.

In the old, old days, I used to have a copy of my target application server on the machine. If I was building an app to deploy to WebLogic Server, then I’d have WebLogic server on my machine and I’d run it using MyEclipse and try out my application. I haven’t done that in years because usually the server software is hard to set up, takes too long to start, and requires way too many resources (memory, etc.).

So for the last few years I’ve been developing my apps on JBoss and deploying them to other servers. Now, some will rightly point out that there’s risk that some other server will behave differently than JBoss and how do I know that I’m gonna get timely feedback about something that won’t work in our target production environment. And that’s a valid line of argument, and I’ve certainly had to debug more than one problem relating to differences between my dev environment and the production server environment. But, if one avoids EJB, I think those differences are few and far between.

But, at the end of the day, I think it’s been a net savings. I spend less time waiting for a server to start up, less time setting up software, and less time trying to get my server to work correctly if I develop on JBoss. Over time, I’ve come to really like JBoss, and I’ve deployed a few production apps on JBoss as well.

But when I say “less time”, that’s a bit of a relative term. Typically, when I want to try something out in the server, I do the following:

deploy the app using the MyEclipse deployment tool

start the server using MyEclipse

start using the app.

That first step has gotten faster and faster with new releases of MyEclipse. On my applications, I find it takes about 10 seconds (or perhaps up to 20 seconds for very complicated applications) to deploy the app to the server. And then the server itself takes something like a minute to a minute and a half to start up. JBoss, alone, can be pretty fast, but I’m not really able to beat those start-up times with anything but the most trivial of web applications.

So, let’s say that it’s about two minutes to get the app running. That’s not too bad, now is it? And hot deploy has usually been pretty helpful. So long as I don’t change method signatures or try to add a new field or method, my Java code hot deploys nicely.

But two minutes. Those two minutes can be a horrible pain, sometimes. I’ve worked with some people who seem to despise how many button clicks you have to do in MyEclipse to get everything going, and they try to put Ant scripts in their place. Me, I’m not annoyed by having to click buttons. But I am annoyed by those two minutes of lost time. (And, to me, it feels like the Ant scripts are slower).

This finally came to a head for me on a recent project when I started using Maven. Now, instead of using the MyEclipse deployment tool, I was essentially forced to use Maven to package up my .war file and add a bit of script-fu to put the .war into my JBoss directory.

When you throw running all the tests into the equation, the Maven package process can take around a minute. Plus a minute and a half to start the server in MyEclipse. And, in this kind of set-up, hot deploy doens’t work anywhere near as well. A minor tweak to a CSS file or HTML page doesn’t get picked up unless I repackage. So I find myself running through this process more often than I did in the past.

Think through the math on that: 2 and a half minutes to redeploy after a minor change. At 480 minutes in a given business day, that means I can try out something like 192 tweaks in a day. That doesn’t seem like a good enough number.

Okay, I try to mitigate the cost of starting the server with unit tests and tools like Dreamweaver and MyEclipse’s page preview, but that’s a serious annoyance.

So recently I decided to try out Jetty. I know there’s a Jetty plug-in for Maven, but I haven’t really been using that. Instead, I built a little executable with an “embedded Jetty” server. My executable loads the web app resources directly from my Eclipse project; no more deploy step. And the whole thing launches in 7 seconds. 7 seconds versus 2 minutes. Not bad, I think.

Now, there are some cautions. First, classpath management. I decided to auto-generate a URLClassLoader for my Jetty server using the .classpath file. But that classpath won’t be identical to what appears in the final .war. (For example, JUnit is on my classpath, but won’t be in the final .war). That’s a risk, but one I’m prepared to live with at the moment. And if it gets to be too big a risk, I can add more smarts to my classloader. Or add some Unit tests to find typical error situations.

It’s also true that Jetty has some minor differences from JBoss. One of the obvious ones is that Jetty doesn’t seem to have a default “download resource” behaviour. If I request a url, like, http://localhost/myImage.png, most application servers will just serve the file out of the web app root. That’s not behaviour that the servlet spec defines, but it’s usually what people want and expect. Jetty, in my experience, doesn’t do that. That’s an easy solution: just add a ResourceServlet, and you’re home free. Beware of the potential security holes, though.

I am, nonetheless, seriously enthused by how much easier/faster it now is to launch the server. Unless something much better shows up, I think this’ll be my new standard configuration for web development.