Application Servers Are (Sort of) Dead!

Recently it crossed my mind there’s something wrong with Java application servers. You know, our team is still using them the way they’re meant. The way they were originally meant. We’ve got many applications running on a common application server that’s managed centrally.

I’m told we’re one of the last companies to do so. These days, most companies dedicate an entire application server to a single application and put them in a virtual machine.

In other words, application servers have become part of the application. Originally, it was meant to be the other way round, and that’s why Eberhard Wolff claims application servers are dead. His JAX talk was a real eye-opener, by the way. He expressed the thoughts that ware already lingering in the subconscious part of my mind. As usual, I’ll mention a few key points of his talk in this post, plus a few thoughts of my own. If you’re interested in the entire talk, have a glance at his slides. He also published an article in the Java-Magazin 7.2014 (in German language, and as far as I know, only available in print).

So what’s wrong with the original idea of applications servers? Let me put the question differently: Have you ever seen an application server that runs out of the box, without being modified?

I guess you haven’t. Almost every application server is modified in one way or another. One of the most common customizations is to add libraries into the shared folder of the application server.

Former versions Tomcat used to have a dedicated folder for that purpose (./lib/ext). The folder has vanished a couple of versions ago, and that’s a subtle hint you shouldn’t share libraries among applications.

In fact, that’s a very bad idea. We used to do the same in the Windows world, and called it DLL hell. It’s pretty astonishing the Java world hasn’t learned from this misery1. Quite the contrary, application servers do even worse than Windows (there’s no counter indicating how many applications use a particular library, let alone which ones). Mind you, what happens when you want to update one of the shared libraries? You have to test every application on the server simultaneously. If a single application isn’t compatible, you can’t update any application (without moving it to another server, that is). Testing applications tends to take a lot of time, so this approach is unreasonable expensive. It’s better to move the jar files from the common folder to the individual application’s folders. Dedicating entire application servers to individual applications is a particular radical approach to that.

As it turns out, this approach has many advantages. Possibly the most important advantage: the responsibility for the application isn’t scattered across departments. Developers deliver both the application and it’s application server. This means they are responsible for choosing compatible libraries. That’s bad in that developers need more time to inform themselves whether one of their libraries has to be updated to fix a security issue. On the other hand they save a lot of time because they don’t have to trace down bugs caused by different libraries on the developer machines and the central server. In the past that has always been a big point of pain, so I daresay the small extra amount of research time is easily outweighed by the time saved. Can you imagine how much time my team and I have spend to find bugs that only happen on the test systems, or even on the production systems? In most cases these bugs are caused by different configuration files, different folder structures or different versions of the same library. Concurrency problems and errors caused by heave load come second, and they’re much more difficult to hunt down and to fix. So the good news that there’s a simple solution for the most common type of “production-only” errors: Let the development department ships prepackaged virtual machines, and this type of errors is a thing of the past2.

You may have noticed by now the title of this article is sort of misleading. I don’t propose to get rid of Tomcat, Jetty, Glassfish, JBoss or which other application server you may be using. Granted, I don’t think it’s a good idea to use a full-blown JavaEE application server. I prefer to use a simple servlet container such as Tomcat or Jetty and to add the jar I want to use. Full-blown application servers contain everything and the kitchen sink, making them feel like supertankers. But that’s another story, and it seems to be a question of personal taste. Today’s story is about the changing role of application servers. They’ve died recently, but only sort of: they live on as part of the application.

There are many other reasons why it’s a good idea not to put many applications on a application server. For instance, your operations department doesn’t have to deal with Java files. I’m told running an application server isn’t exactly their primary field of expertise (at least if your operations department is specialized in managing UNIX systems). Another interesting point is Java applications stop to “steal” each other’s resources and much more. Application servers go to great lengths to make you believe the applications are independent of each other, but that remains a fiction. The applications are separated (for example, they have their own class loaders), but only to a certain extend. An application running havok quickly brings the entire server into trouble. Virtual machines are better prepared to deal with these problems.

At this point I’d like you to point you to Eberhard Wolffs slides or his Java-Magazin article instead of exploring the details further.

It’s time to get our feet wet and start writing code.

How to package an application and it’s application server?
Eberhard Wolff – being big into Spring – suggests to use Spring Boot, which is an interesting product indeed. Another – fairly radical – way is to ship virtual machines. That’s what a friend of mine does, and he’s reporting he’s made very good experiences with this approach. I’d recommend shipping virtual machines if you have little to none control over (or knowledge of) the target system.

Alternatively you can run Jetty embedded. Basically, that’s simply adding a couple of jars and writing a main method like so:

package org.eclipse.jetty.embedded;
 
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
 
public class OneContext {
 
    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);
        ContextHandler context = new ContextHandler();
        context.setContextPath("/");
        context.setResourceBase(".");
        context.setClassLoader(Thread.currentThread().getContextClassLoader());
        context.setHandler(new HelloHandler());
        server.setHandler(context);
        server.start();
        server.join();
    }
}

Read the full story in the Jetty documentation.

Embedding Tomcat is just as simple, as you can read here.

Without having investigated I suspect it’s a lot more difficult to embed a full-blown JavaEE application server (such as Glassfish or JBoss) into your application. That’s one of the reasons why I prefer to use Jetty or Tomcat. The idea is to keep simple things simple.

No need to deploy!
Once your application runs an embedded Jetty or Tomcat, you’ll notice you’re working much more interactively than before. Every class you’ve changed is immediately reloaded, every modification of a JSF or JSP file immediately shows up in your program and so on. Only a few changes (Spring config files and web.xml) require a restart of your server, which boils down to a simple restart of your main class.

Granted, most modern IDEs do a good job at providing features like hot code replacement. In many cases they provide an interactive developing experience, so there’s little to complain. However, I daresay things feel a little smoother running an embedded server. It’s quite a challenge to provide hot code replacement with a non-embedded server. Mind you, the complete cycle includes packing a war file just to have it unpacked by the server. That’s sort of ridiculous if you’ve just corrected a single typo. Eclipse implements quite a few shortcuts of the deployment cycle, but nothing beats an embedded server: there’s no need to deploy the application. It’s ready for use, out of the box.

Embedding Tomcat or Jetty frees you from having to package and deploy your application. That’s a major advantage because you don’t have to think about things like hot code replacement. It just works. As to my experience, development becomes a lot more fun, more interactive and of course faster.

Embed the browser
You can even go a step further and embed the browser, too. That’s a nice feature for developers. Even if hardly anybody want to embed the browser in production, it’s an interesting thought: instead of shipping pre-packaged application servers to the operations departement, you can ship the application, its application server and its embedded browser to the client. You end up with a traditional desktop application: it’s started by a double click, opens a window and closing the windows also shuts down the entire application server. The only drawback is a slightly higher demand of server resources that are tradionally shared among clients (database connections, in particular).

In any case, it’s a nice tool for developers. All you have to do is to add SWT to your libraries. You can use one of SWT’s examples as a starting point: your default browser (i.e. Internet Explorer on Windows systems), Mozilla (aka Firefox) or WebKit (Safari, older versions of Google Chrome).

Basically, the code needed is very simple:

public static void main(String [] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setLayout(new FillLayout());
	shell.setText("WebKit");
	final Browser browser;
	try {
		browser = new Browser(shell, SWT.WEBKIT);
	} catch (SWTError e) {
		System.out.println("Could not instantiate Browser: " + e.getMessage());
		display.dispose();
		return;
	}
	shell.open();
	browser.setUrl("http://webkit.org");
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch()) display.sleep();
	}
	display.dispose();
}

Start the application server in another thread and you’re done. On the long run you’ll probably add more code (for instance, to support the Javascript methode Window.open) – but even so, the source code of the browser we’re using at company fits nicely on two or three pages in print. (We invented this mechanism to get rid of compatibility issues with the pre-installed browsers – but that’s another day’s story).

Conclusion
Application server’s aren’t really dead – I just couldn’t resist to use the title. But nowadays they’re frequently used differently than they were designed to be used. Instead of embedding an application into a server, things are done the other way round, and as it turns out, this simplifies the developers’ lifes considerably. As a bonus, you can even embed the browser and ship the application as an almost traditional desktop application. Loosening the restrictions imposed by the browsers security system even allows you to escape the sandbox and to access the desktop machine’s resources (e.g. local files). Granted, this isn’t really something I’d suggest (you’re better off using dedicated APIs such as JavaFX or even chosing another language ecosystem with better GUI support, such as VisualBasic or C#). Nonetheless this is an interesting idea closing the circle opened one or two decades ago by propagating thin client applications.

Reader feedback
This article has been bookmarked on Reddit. A surprisingly big number of readers agrees: even if the single-app-per-server model I describe above is not adopted by everyone, the general trend is to reduce the number of applications per server. However, doing the last step and using distributable jar files containing the server seems to be a fairly new idea: it wasn’t discussed at all yet. Come on, give it a try!


Further reading:
Application Servers are dead! (Eberhard Wolff’s slides)
Java-Magazin 7.2014
The discussion on Reddit about this article
Spring Boot and JSF in practice

Spring Boot + JSF template projects:

simple PrimeFaces project on Spring Boot
PrimeFaces, Spring Boot, JSF custom scopes and Spring custom scopes.


  1. Truth to tell, the Java world has learned the lesson. But it seems to have forgotten what it once learned.
  2. But please don’t underestimate the amount of time it takes to track security issues. Developers tend to neglect security issue because it distracts them from developing new, fancy features, so this is an important point to keep in mind).

6 thoughts on “Application Servers Are (Sort of) Dead!

  1. jose

    Hi, its 2015 and its not truth
    “I’m told we’re one of the last companies to do so. ”
    I know several companies, not in Third world countries, companies in Europe at very good countries are still using weblogic and others app servers. So thats not truth.

    Reply
    1. Stephan Rauh Post author

      Peace :). I can’t say I like heavy-weight servers like WebLogic, WebSphere and so on, but this particular sentence didn’t say anything against them. What I wanted to say is that recently a “One server per application” policy has become popular. Or more than one server. The bottom line being that every application server instance hosts only a single application. In former times, the idea was to use an application server instance for multiple applications.

      BTW: I won’t ever say anything patronizing about third-world-companies. Many people find themselves in the uncomfortable situation to live in one of the poorer countries of the world, but that doesn’t mean they aren’t clever.

      Reply
  2. Thrawn

    Our team used to have many WAR files per application server, but increasingly we ran into library conflicts, where different applications expected different versions of Quartz, OpenSAML, etc. To make things even more Fun, these conflicts often depended on the order in which applications were started, which often seemed to be arbitrary.

    Now, we separate them. We use Jetty, so the overhead per server is minimal. We can start and stop the individual Jetties independently of each other, which is nice for deploying changes. We can also make more use of the out-of-the-box configuration, because each server needs just one port number, just one location for classpath resources, just one log directory, etc. Someday we’ll probably virtualise or containerise each one, and the JETTY_BASE won’t need to change significantly. Altogether a much cleaner setup.

    Reply
  3. Anton Tomanek

    Had a chance in last 4-5 months to work in completely in docker ready environment, we used latest of the latest version of cloud hype, Kafka, arangodb, spark, ….
    It is really easy to setup let say 2-6 server on developer machine, with your apps, servers, …..
    In fact if you check docker hub most of servers you want to use, most of the linux distros, are there.
    And once you develop your app, and prepare it, deployment to amazon, whatever linux/docker provider around is nothing.
    And yes times when lib from Tomcat, needed to run was in conflict with ours are somehow gone.

    Reply
    1. Stephan Rauh Post author

      I’m told it take quite a few preparations to get “Docker ready”, but once you’ve managed to embrace Continuous Delivery, it’s starting to pay off. It seems you entered the project during the second phase. Do you know by any chance how much work it was to get there? How expensive is it to get Docker ready?

      Reply

Leave a Reply

Your email address will not be published.