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
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
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
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, a good practice consists in keeping a regular Jar and providing a Fat Jar as an additional option.
Ideally, dependency classes should also 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
Now, invoking jeka prpject: pack
will also create a*org.examples.my-lib-all.jar* file.
By opening the jat file, we can see that all dependency classes has been automatically re-located.
.
├── 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
Additionally, @maven.publication.extraArtifacts=all
includes the shade jar in the maven publication generated by jeka maven: publish
command.
Maven Comparison
As shown 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>2.3</version>
<executions>
<!-- Run shade goal on package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<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>
</pluginManagement>
</build>
</project>
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!
Top comments (0)