Fine grained fat Jar in Gradle

Gradle Cookbook has a one liner to produce a fat jar. But what you want to make it just a bit more slim? In my case I wanted to exclude parts of external dependencies which I do not use, licensing files (I had licenses mentioned in a separate folder already) and other kinds of useless load. To do this I wrote two helper functions:

def smallJars(limit) {
  configurations.compile.findAll {it.length() < limit}.collect { it.isDirectory() ? it : zipTree(it) }

def locateJar(lib) {
  configurations.compile.findAll {it.getName().contains(lib)}.collect { it.isDirectory() ? it : zipTree(it) }

The idea is to include any small Jar automatically, but force developer to specify each bigger Jar separately in order for it to be included. For example:

jar {
  from { smallJars(30000) }
  from { locateJar('scala-library') } {
    include '**/*.class'
    exclude 'scala/beans'
    exclude 'scala/collection/parallel'

Using this simple method I was able to shrink my Jar by 30% without loosing any important classes and spending too much time.

This code does not handle directories properly - it does not calculates the size of a directory.

You could also use ProGuard or other Jar shrinker instead. But it has disadvantage of having to wait longer for Jar to be produced and is a lot less reliable if you use Scala.