Making a fully packaged Jarfile with all dependencies with gradle

This blog post talks about how you can create a fully packaged jarfile including all its gradle dependencies.

What is a fully packaged jar file also known as a fat jar or uber jar

When using gradle dependencies it will download the various required files and have them available. When running in the IDE it will add these libraries to your class path so your code can access them.

However when you produce a standard jar file unless you put all your dependencies library jar’s in the same location it will fail to run normally.

In my test repository I can run the created jar but it fails with a message explaining that it is missing some dependencies as shown below.

Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/Gson
        at net.chewett.github.gradlepackagedjarexample.GradleImportTest.main(GradleImportTest.java:9)
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 1 more

To ensure your jar file includes all dependencies you need it to include you can “package” up these dependencies into the jar file. This jar is also sometimes called a fat jar or an uber jar.

Creating a fully packaged jar file/fat jar/uber jar

To create a fully packaged jar file you will can create a new gradle task to include all compile time files. An example of this is below

task goodjar (type: Jar) {
    manifest {
        attributes "Main-Class": "net.chewett.github.gradlepackagedjarexample.GradleImportTest"
    }
    archiveBaseName.set(project.name + '-good')
    from {
        configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    } with jar
}

This will create a jarfile including all required dependencies that will launch the main class:

net.chewett.github.gradlepackagedjarexample.GradleImportTest

By doing this all dependencies in the dependencies section that are required for implementation are included in the jarfile.

When I run my new jar gradle command it will now correctly run and use the Google GSON library noted as missing above.

JSON int array converted from a string by Gson
[1, 2, 3, 4, 5]

A git repository showing this working is available on github.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.