Über jars vs thin wars, pros and cons

This post was inspired by a Twitter conversation with Reza Rahman where, as far as it goes on Twitter, the relative merits of using Über jars as opposed to thin wars were being bandied about.
My first post on my new blog is also quite a long one, please bear with me.

A little history

There is a growing tendency in the industry to move away from the traditional monolithic application run on a fully tooled up application server towards running apps defined by the single service they provide, the so called microservice. Here the emphasis is reducing the application to providing independent support for one thing .
The idea behind the microservice is the microservices architecture where a set of loosely coupled microservices are used to build applications using them. 

This has, in turn, driven the development of application servers better suited to running microservices in them. The industry's response to the demand for microservices support has been the forming of the Micro Profile Initiative, a consortium of experts substantially supported by the leading industry players in the business.

There are many good reasons for going down the microservices architecture  road, there are also some very important issues being glossed over in the rush to hype it too. I am not going to be discussing that here apart from saying that the issues are not being ignored and you can educate yourself by checking out some of the recent Oracle Dev streams on YouTube, for example.

Über jars?

What is this thing and why would we want it?
The rather German looking word means "over", in this context it really means "everything". The term was first coined, as far as I know, by developers who thought it was a good idea to throw all dependencies and your own code into one jar file and solve the, nightmarish, problem of class conflicts that inevitably occur. Because the German Ü is not easily available on most keyboards you will see this as plain old Uber.

In the context of microservices an Über jar is a form of packaging where your entire service and the server it runs in are bundled into one jar file. The advantage of this is that you simply need to use the java -jar MyUberJar.jar to spin it up and get it running.

Spring Boot are definitely advocates of Uber jar deployment however even they are beginning to see that, perhaps, the idea is not as great as it sounds.
The vendors involved in the Micro Profile Initiative are also on board with this and provide you with the ability to create Über jars for their Micro Profile application container.

Thin wars

A war file is how an application is packaged for deployment in a standard Java application server. These days you can also package EJBs in them, once the domain of ear packaging (enterprise archive), which is a really good thing. The thin part comes from the fact that you only package your business logic and UI. Any third party dependencies like PrimeFaces etc, you will also need to package with it. Everything else should be provided by the application server you want to run your application on. This is the exact opposite of an Über jar.
Because microservices should be as lightweight as possible packaging them as a thin war means the resulting file size and deployment times are at a minimum. Obviously you need to have a running application server to deploy them to, something I will address later.

Über jar vs thin wars

After the rather long preamble we come to the meat of the actual discussion: which is better?

I have to admit, I am not a real fan of Über jar packaging but there are often political forces at work which removes the choice of technology from your hands.

Pros for Über jars

Having everything in one file means you can simply distribute it to wherever you need it to run and, assuming that all the other required services are available, run it like any other java executable.
Because it is becoming easier to choose the application container of choice (sorry Spring Boot) for your Über jar this is no longer a barrier to deploying your app in this fashion.
You do not need to have a preinstalled application container available.
Easier to test the application against the services API.

Cons against Über jars

Your business logic and application container are all in one file. Yes, the pro is a con and not an insignificant one. When your business logic changes, which it will, then you have to ship another copy of the application container, which hasn't changed, with it. If you have only changed 1 class then that overhead becomes much more significant.
Spinup times are higher compared to the deployment of a thin war to a running application container.

Pros for thin wars

File size: you are not packaging anything other than the business logic and its immediate dependencies. Because of this you are not distributing copies of the application container.
Thin wars are a much better fit for containerisation. More on this later.
Deployment of the application itself is lower when not taking account of application container startup times.
You are not locked in to the application container you are deploying to, the caveat being your application doesn't leverage implementation specific container features.

Cons against thin wars

You need more infrastructure in place before you can deploy: the application container.
Unless you also include the distribution and configuration of your application container into your CI/CD chain this can become a showstopper.
More effort is needed to test your application against the Service API. This can be a trivial amount of effort though.

Containerisation

With container based distribution and deployment using systems like Docker becoming more mature and of viable production strength the lure of the Über jar loses its shine.
Without going into any detail the way in which Docker leverages the concept of layered images and caching make the deployment of an Über jar as opposed to a thin war much less attractive.

Reza Rahman gave me a link where the problems, and their solutions, of Über jar deployment in a docker container involving Spring Boot are discussed. My take on that is that there is way too much effort being made to overcome problems that a thin war Docker deployment simply never has. IN short, they explode the Über jar into an image and distribute that, thus losing any advantage an Über jar deployment may have had.

In conclusion, and if you got this far thanks for sticking with me, my take is this: both Über jar and thin war deployments are viable alternatives you can use for getting your microservices out there.
But the choice of which to use should always be the one most optimal for the job.

I am not a fan of Über jar deployment and I certainly would not advocate its use where containerised deployment is being used. I would use it where its use is more effective than other alternatives: Proof of Concepts, demos for the most part. 


Comments

  1. Another reason to use über jars is the update hell you run into using traditional application servers. The traditional approach is to use a single application server for multiple applications. If you do so, updating the application server means that you have to test (and possibly modify) every application running on this application server. Simultaneously. Luckily, most operation departments have recognized this as a problem and dedicate an application server to each application. Which is pretty close to using an über jar.

    Closely related is that you know precisely what you ship in an über jar. Using an application server, you don't know. The application server may be updated at any point of time, breaking compatibility to your application.

    Sometimes the operation department insists on installing common libraries such as PrimeFaces on the application server. There may be good reasons for this (usually licensing), but it also means that developers and architects can never update these libraries themselves. I've been working many years in a very conservative company. On average, updates were installed three to five years late. In such an environment, über jars become very attractive.

    Of course, many of these points have something to do with corporate politics. If you're adopting devops, you'll never encounter these problems (or at least, you can do something about them).

    Another interesting point may be the skill set of the operations department. Often, the operations guys are very familiar with Unix, but less familiar with Java. If so, you may be better off with über jars because they make the developers responsible for the entire Java stack.

    BTW, some of these arguments can easily be turned around: using an über jar means that the operations department can't deploy an important security patch.

    Cutting a long story short, often the reason to chose über jars has little to do with technology. Like so often, it depends on your team to decide with solution suits you best.

    ReplyDelete
    Replies
    1. By the way, here are a few links explaining the pro of über jars in much more detail:

      https://jaxenter.com/java-application-servers-dead-112186.html

      https://de.slideshare.net/ewolff/java-application-servers-are-dead

      https://www.beyondjava.net/blog/application-servers-sort-of-dead/

      Delete
  2. Thanks for the comments and the links, which I will read when I get the time.
    I will be publishing my take on devops and application servers drawing on my experiences developing a complete CI/CD chain for a multi-application system soon which will address some of the serious issues you mentioned in your first comment.
    An intermediate solution, hollow über jars, looks promising and goes someway to addressing the problems with containerised über jars.

    ReplyDelete

Post a Comment