I recently made use of ProGuard to reduce the size of a jar through tree shaking. Tree shaking is basically the art of holding the software upside down in the roots and shaking it so that you only keep the classes and methods you need.

There is a Maven plugin called proguard-maven-plugin that allows you to run ProGuard from your Maven build with ease.

How to use this plugin in a way that cooperates well with the standard Maven Shade plugin was not entirely straightforward and I’d like to share some of my findings.

Plugin Management / One Config to Rule Them All

It turns out that the proguard-maven-plugin works really well together with the Maven “plugin management feature. If you have not heard of it please read more here: https://maven.apache.org/pom.html#Plugin_Management

An imagined company super pom:

With such a super pom we can simply add ProGuard processing using the following short addition the actual Maven project:

Now you can put all ProGuard specific configuration in the file “proguard.conf” in your base dir. An example of this layout and how I used it can be seen in these projects:

Before or after Shade?

The proguard-maven-plugin applies ProGuard to the project itself. That means you should shade in any external libraries using maven-shade-plugin before you use the proguard-maven-plugin. In practice this means proguard-maven-plugin should be furtherst down in your pom.xml.

ProGuard itself operates the best when you supply it with loads of so called libraryjars. The proguard-maven-plugin helps out by automatically adding known Maven dependencies as library jars. This is a great feature that we want to make use of. It usually works fine, but if you use the “relocate” feature of Maven shade the library jars may no longer link properly. Because of this I have actually made use of a multi step build in my case. MassiveCoreXlibGuava is just a tree shaked Guava. In MassiveCoreXlib I relocate that treeshaked Guava into another Java package. I’m not sure this is 100% necessary but it allows me to keep things isolated and easier to debug.

Picking the Right Java JDK libraryjars

For some odd reason it seems you have do supply certain JDK libraryjars yourself. Take a look at this proguard.conf example:

The section I’m going to discuss is this one:

So I basically did the following:

And came up with these initial libraryjars:

Then I commented out the “-dontwarn” line at the beginning of proguard.conf and tried removing one at a time. If the warning count increased I added it back. Other wise I kept it in place.