Chapter 12. The Case Against Fat JARs

Daniel Bryant

In modern Java web development, the thought of packaging and running applications in anything other than a fat JAR is almost becoming heretical.  However, there can be distinct disadvantages to building and deploying these artifacts.  One obvious issue is the typically large size of fat JARs, which can consume excess storage space and network bandwidth. In addition, the monolithic build process can take a long time and cause developers to context switch while waiting. The lack of shared dependencies can also cause inconsistency across the use of utilities, such as logging, and challenges with integration of communication or serialization across services.

The use of fat JARs for deploying Java applications became popular alongside the rise of the microservice architecture style, DevOps, and cloud-native technologies, such as public cloud, containers, and orchestration platforms. As applications were being decomposed into a collection of smaller services that were being run and managed independently, it made sense from an operational perspective to bundle all of the application code into a single executable binary. A single artifact is easier to keep track of, and the standalone execution removes the need to run additional application servers. However, some organizations are now bucking the trend and creating “skinny JARs.”

The HubSpot engineering team has discussed how the challenges listed above were impacting their development life cycle in a blog post, “The Fault in Our JARs: Why We Stopped Building Fat JARs”. They ultimately created a new Maven plug-in: SlimFast. This plug-in differs from the classic Maven Shade plug-in that the majority of Java developers are familiar with, in that it separates the application code from the associated dependencies and accordingly builds and uploads two separate artifacts. It may sound inefficient to build and upload the application dependencies separately, but this step occurs only if the dependencies have changed. With many applications the dependencies change infrequently, and so this step is often a no-op; the package dependencies’ JAR file is uploaded to remote storage only a minimal number of times.

The SlimFast plug-in uses the Maven JAR plug-in to add a Class-Path manifest entry to the skinny JAR that points to the dependencies’ JAR file, and generates a JSON file with information about all the dependency artifacts in S3 so that these can be downloaded later. At deploy time, the build downloads all of the application’s dependencies, but then caches these artifacts on each of the application servers, so this step is usually a no-op as well. The net result is that at build time, only the application’s skinny JAR is uploaded to the remote storage, which is typically only a few hundred kilobytes. At deploy time, only this same thin JAR needs to be downloaded to the target deployment environment, which takes a fraction of a second.

One of the core ideas behind the emergence of DevOps is that the development and operations team (and all the other teams) should work together for a common goal. The choice of deployment artifact format is an important decision within the goal of being able to continuously deploy functionality to end users. Everyone should collaborate in order to understand the requirements in relation to how this impacts the developer experience and ability to manage resources involved in deploying.

The SlimFast plug-in is currently tied to AWS S3 for the storage of artifacts, but the code is available on GitHub, and the principles can be adapted for any type of external storage.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.136.170