Ü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.
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.
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.
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.
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.