Fork me on GitHub

Why another plugin to repack dependencies?

Repackaging a jar or war archive with all its dependencies to become a single archive is a common task when operating software on the JVM.

Historically, there have been many different ways to accomplish this. For Apache Maven, there are a number of plugins, such as:

  • Maven Shade Plugin - The “classic” way to repackage dependencies
  • Maven Assembly Plugin - Layout classes and dependencies using flexible assemblies
  • Inline plugin - Easily create components that have external dependencies but should not “bleed” these dependencies into other code
  • JarJar plugin - repackage dependencies inside a project artifact to avoid classpath conflicts
  • Spring Boot Maven Plugin - The Spring Boot Maven Plugin […] allows you to package executable jar or war archives

Most of those approaches rewrite the class files and “flatten” all entries in the various classpath dependencies into a single jar. This is problematic for many reasons:

  • Code may inspect class names and rely on specific, hard-coded package or class names, so repackaging breaks this
  • Classpath artifacts are signed and can not be repackaged
  • Entries may occur multiple times (especially in the META-INF directory) and flattening them either overrides them or logic must exist to combine them

The most promising way to repackage code is the Spring-Boot plugin, which

  • packages the contents of the original jar unchanged into a special directory (BOOT-INF/classes) or keeps it as-is (META-INF content)
  • packages dependencies into BOOT-INF/lib
  • adds custom startup code (JarLauncher) that creates the necessary classloaders and optionally unpacks dependencies that need special treatment.
  • adds only a few entries to the manifest file.

Unfortunately, the spring boot plugin itself is (for understandable reasons) geared towards use with the spring-boot ecosystem. Using it for non-spring applications requires some additional tweaking (and expects the spring libraries being packaged with the code even if they are not in use).

This plugin is a stripped down version of the wrapper code around the Repackager functionality found in the spring-boot-loader-tools. It can be used with any JVM project that has a main class; especially it can be used as a replacement for using the Apache maven-shade-plugin when creating standalone jar applications.