How to create an uber-jar out of a kjar and its dependencies

We recently had a request for the ability to bundle a kjar and its dependencies into one uber-jar, as opposed to relying solely on dependency management mechanisms.  Since a kjar is essentially just a Maven project, we can utilize the maven-shade-plugin to handle this for us.

Note that at the time of this posting, this functionality is not currently possible via the jBPM Workbench.


Let’s assume that in a separate module, you have created a model object, Person.  The Person POJO contains the following dependencies:

 <dependency>
   <groupId>io.swagger</groupId>
   <artifactId>swagger-jaxrs</artifactId>
   <version>1.5.0</version>
   <scope>provided</scope>
 </dependency> 

 <dependency>
   <groupId>info.cukes</groupId>
   <artifactId>cucumber-junit</artifactId>
   <version>1.2.5</version>
 </dependency>

Let’s assume your kjar is contained in a separate module with a dependency on the above model class:

 <dependency>
   <groupId>org.demo</groupId>
   <artifactId>demo-model</artifactId>
   <version>1.0-SNAPSHOT</version>
 </dependency>

We can include the following in our kjar pom in the <build> section:

...
 <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-shade-plugin</artifactId>
   <version>3.1.0</version>
   <executions>
     <execution>
       <phase>package</phase>
       <goals>
         <goal>shade</goal>
       </goals>
       <configuration>
         <transformers>
           <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
             <mainClass>org.demo.model.Person</mainClass>
           </transformer>
         </transformers>
      </configuration>
     </execution>
   </executions>
 </plugin>
 ...

Since we have defined the main class as our Person object, this class + any transitive compile dependencies of it will be extracted and included with our kjar classes/resources.

If we rebuild our kjar, we should find that it includes not only the Person class, but all of its dependencies (including those which are transitive!).

Before creating the uber-kjar:

[anbaker@localhost target]$ jar tf demo-kjar-1.0-SNAPSHOT.jar 
META-INF/
META-INF/MANIFEST.MF
META-INF/kmodule.xml
rules.drl
META-INF/maven/
META-INF/maven/org.demo/
META-INF/maven/org.demo/demo-kjar/
META-INF/maven/org.demo/demo-kjar/pom.xml
META-INF/maven/org.demo/demo-kjar/pom.properties

After creating the uber-kjar:

[anbaker@localhost target]$ jar tf demo-kjar-1.0-SNAPSHOT.jar 
META-INF/MANIFEST.MF
META-INF/
META-INF/kmodule.xml
rules.drl
META-INF/maven/
META-INF/maven/org.demo/
META-INF/maven/org.demo/demo-kjar/
META-INF/maven/org.demo/demo-kjar/pom.xml
META-INF/maven/org.demo/demo-kjar/pom.properties
org/
org/demo/
org/demo/model/
org/demo/model/Person.class
META-INF/maven/org.demo/demo-model/
META-INF/maven/org.demo/demo-model/pom.xml
META-INF/maven/org.demo/demo-model/pom.properties
cucumber/
cucumber/api/
cucumber/api/junit/
cucumber/api/junit/Cucumber.class
...

It is important to note that the dependencies on swagger-jaxrs will not be extracted and included with our uber-kjar, as it has a scope of provided.

The maven-shade-plugin also offers the ability to relocate classes, which might come in handy if your kjar relies on a particular dependency version that differs from what the server provides.  I found this tutorial helpful in walking through that process.

The demo project (including unit tests) is located here, should you wish to see it in action.

As always, if you have any questions, please comment below.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s