DEV Community

Cover image for JeKa: The Simplest Way to Create Uber and Shade Jars
Jerome Angibaud
Jerome Angibaud

Posted on • Edited on

3

JeKa: The Simplest Way to Create Uber and Shade Jars

Edited 2025-10-15: Fix the Maven pom.xml sample.

JeKa is a modern Java build tool focused on simplicity.

This post is part of the "Jeka: the simplest way to..." series and shows how to create a fat jar (shaded or not) effortlessly.

For Applications : Simple Fat Jar

A common way to package Java applications is by creating FAT jars. A fat jar bundles all classes from the dependencies, so you only need the jar (along with the Java Runtime) to run the application.

Your application may need dependencies, which you can list in the dependencies.txt file as shown in the example below:

== COMPILE ==
com.github.lalyos:jfiglet:0.0.9
com.google.guava:guava:33.4.0-jre
com.fasterxml.jackson.core:jackson-core:2.18.2

== TEST ==
org.junit.jupiter:junit-jupiter:5.8.1
Enter fullscreen mode Exit fullscreen mode

To configure the fat jar generation, edit the jeka.properties file:

jeka.version=0.11.11
jeka.java.version=17

@project.pack.detectMainClass=true
@project.pack.jarType=FAT
Enter fullscreen mode Exit fullscreen mode

The @project.pack.jarType property specifies the type of JAR to generate. It can be REGULAR, FAT, or SHADE.

The @project.pack.detectMainClass=true setting instructs Jeka to detect the main class to include in the manifest file.

To generate the jar, run the following command:

jeka project: pack
Enter fullscreen mode Exit fullscreen mode

The FAT jar will be created in the jeka-output directory. To run it, just execute: java -jar [jar-name].jar.

For Libraries : Shade Fat jar

For libraries, an established practice consists in keeping a regular Jar and providing a Fat Jar as an additional option.

In some situation, such as a version clash, dependency classes should be relocated to a specific package to avoid classpath conflicts for the consumers. We call a shade jar, a fat jar where the dependencies classes have been re-located in a specific package.

To create such a jar, configure JeKa as follows:

jeka.version=0.11.11
jeka.java.version=17

@project.moduleId=org.examples:my-lib
@project.version=1.0.0-SNAPSHOT
@project.pack.shadeJarClassifier=all

@maven.publication.extraArtifacts=all
Enter fullscreen mode Exit fullscreen mode

Now, invoking jeka prpject: pack will also create a org.examples.my-lib-all.jar file.
By opening this jar file, we can see that all dependency classes has been automatically relocated.

.
├── org                  
│   └── example             
│       └── mylib           <- Base package for my-lib classes
│           ├── MyLyb.class   
│           └── _shaded     <- Base package for dependency classes
│               ├── com.google...
│               ├── com.fasterxml.jackson...
│               └── com.github.lalyos.jfiglat...
└── META-INF             
    └── MANIFEST.MF      

Enter fullscreen mode Exit fullscreen mode

Additionally, adding @maven.publication.extraArtifacts=all to jeka.properties, includes the shaded JAR in the Maven publication generated by the jeka maven: publish command.

Maven Comparison

As demonstrated below, Maven requires significantly more typing to achieve a similar goal.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.examples</groupId>
   <artifactId>my-lib</artifactId>
   <version>0.1.0-SNAPSHOT</version>
   <dependencies>
      <dependency>
         <groupId>com.github.lalyos</groupId>
         <artifactId>jfiglet</artifactId>
         <version>0.0.9</version>
      </dependency>
      <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
         <version>33.2.1-jre</version>
      </dependency>
      <dependency>
         <groupId>com.fasterxml.jackson.core</groupId>
         <artifactId>jackson-core</artifactId>
         <version>2.17.2</version>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
               <minimizeJar>true</minimizeJar>
               <artifactSet>
                  <includes>
                     <include>com.google.guava:guava</include>
                     <include>com.github.lalyos:jfiglet</include>
                     <include>com.fasterxml.jackson.core:jackson-core</include>
                  </includes>
               </artifactSet>
               <relocations>
                  <relocation>
                     <pattern>com.google.common</pattern>
                     <shadedPattern>org.elasticsearch.common</shadedPattern>
                  </relocation>
                  <relocation>
                     <pattern>com.fasterxml.jackson</pattern>
                     <shadedPattern>org.elasticsearch.common.jackson</shadedPattern>
                  </relocation>
               </relocations>
               <filters>
                  <filter>
                     <artifact>*:*</artifact>
                     <excludes>
                        <exclude>META-INF/license/**</exclude>
                        <exclude>META-INF/*</exclude>
                        <exclude>META-INF/maven/**</exclude>
                        <exclude>LICENSE</exclude>
                        <exclude>NOTICE</exclude>
                        <exclude>/*.txt</exclude>
                        <exclude>build.properties</exclude>
                     </excludes>
                  </filter>
               </filters>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>
Enter fullscreen mode Exit fullscreen mode

Conclusion

Jeka makes building Java projects significantly easier, with minimal configuration compared to Maven or Gradle.

Explore more examples to discover how Jeka can adapt to your project’s needs!

Billboard image

The fastest way to detect downtimes

Join Vercel, CrowdStrike, and thousands of other teams that trust Checkly to streamline monitoring.

Get started now

Top comments (2)

Collapse
 
khmarbaise profile image
Karl Heinz Marbaise

The given example for Maven duplicates the maven-shade-plugin, uses different versions of the plugin (apart from that, hose version are ancient old ca. a decade old!), explicitly defines the binding of the plugin to the package phase which is simply not required nor does it make sense... Also I would ask here why is the relocation required? Using a shaded jar as a dependency is the dead of your dependency propagation...

Ideally, dependency classes should be relocated to a specific package to avoid classpath conflicts for the consumers.

Simply no... because I as a consumer will be able to overwrite transitive dependencies if I have to ... simple use cases which happens very often are for example security issues with particular versions of dependenc(y/ies) (or something else; because I have other libs which use different versions)... if you use only the shaded jar you are simply lost or even worse you don't even realize it...

How does JeKa configuration handle the issues with duplicate files from different jar files like MANIFEST.MF, multi release JAR configuration (module-info) or code for particular JDK versions META-INF/versions/17/...(as an example?) , or other resources like xml files, signatures of JAR files, or META-INF/services etc. ?

Collapse
 
djeang profile image
Jerome Angibaud • Edited

Thank you for your feedback.

For the Maven example, I just used one I found via Google. If you have a better, more relevant, and efficient sample, I’d be happy to update the article with it.

You're correct that you cannot override re-located dependencies. The property

@maven.publication.extraArtifacts=all
Enter fullscreen mode Exit fullscreen mode

configures the publication of an extra shade artifact alongside the original one. The consumer can choose to use either the shaded or regular dependency, depending on their needs. I'll mitigate the part of the article you mentioned.

For details, the implementation relies on the Maven Shade Plugin.

JeKa doesn't aim to be exhaustive in rendering this functionality upfront but focuses on making it simple from the user's point of view. The API surface will grow as needs and constraints, raised by users, emerge.

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay