How to build a FatJar using Maven?

banner

Maven is one of the most used tools for Java application development.

Maven packaging will create a Jar file without dependencies.

Maven provides other plugins using which we can generate the jar with all its dependencies which is usually called FatJar, which is used as an executable Jar file.

These Fat Jars are mostly useful to build executable jar file, for suppose, if we are developing a microservice, if we don’t create fat jar file, we need to all its dependencies in one folder, add this folder to the classpath, and start the microservice, for each time we need to do these steps in manually, but if we generate the fat jar as it includes all its dependencies, not needed to add to the classpath, we can directly run the command to start the microservices. The same will be applicable for docker images, as we can pass the single command to start the docker container.

Maven provides different ways to generate the Fat jar:

Apache Maven Assembly Plugin:

Add the below Maven plugin in pom.xml file:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.4.1</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>org.sample.Application</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>

Note: if the project has no main class then we can omit the archive section.

descriptorRef is the name that will be appended the package name.

The phase is used to specify when this maven goal should execute, suggest to specify the package because when we invoke mvn package, these jar with all dependencies will also be generated.

Maven has proved to be a useful tool required for development of a JAVA application.

Visit us and acquire the extensive knowledge of developing executable Jar files.

The drawback of this plugin is some class with the same package is added to the classpath, this assembly plugin will have only class.

Relocating classes feature is not supporting in the above plugin.

Maven provides another plugin shade-plugin will have this feature if the duplicate package names are present we configure with alternate package names.

Apache Maven-Shade-plugin:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <relocations> <relocation> <pattern>org.sample.plexus.util</pattern> <shadedPattern>org.shaded.sample.plexus.util</shadedPattern> <excludes> <exclude>org.sample.plexus.util.xml.pull.*</exclude> </excludes> </relocation> </relocations> </configuration> </execution> </executions> </plugin>

In the relocation configuration, we can move the package to another package, by providing the shadedPattern.

This plugin also supports, if some of the packages are not using in the Application security solutions, we don’t need in the final fat jar, we can exclude those package in the exclude section, which will improve the class loading performance.

For suppose, if a jar file contains 10 packages, but we are using only one package, then instead of excluding 9 packages, include 1 package.

We can use includes tag similar excludes.

Review fat jar:

Execute the below command to observe the fat jar folder structure:

jar tf target\magellan-connector-msexchange-online-graph-cmis-1.0.0-SNAPSHOT-jar-with-dependencies.jar

Third-party libraries are also available to prepare fat jar like one-jar maven plugin etc.

META-INF/ META-INF/MANIFEST.MF org/ org/apache/ org/apache/chemistry/ org/apache/chemistry/opencmis/ org/apache/chemistry/opencmis/server/ org/apache/chemistry/opencmis/server/support/ org/apache/chemistry/opencmis/server/support/filter/ org/apache/chemistry/opencmis/server/support/query/ META-INF/DEPENDENCIES META-INF/LICENSE META-INF/NOTICE org/apache/chemistry/opencmis/server/support/CmisServiceWrapper.class org/apache/chemistry/opencmis/server/support/filter/JsonPrettyPrinter.class org/apache/chemistry/opencmis/server/support/filter/LoggingFilter$LoggingInputStream.class org/apache/chemistry/opencmis/server/support/filter/LoggingFilter$LoggingOutputStream.class org/apache/chemistry/opencmis/server/support/filter/LoggingFilter$LoggingRequestWrapper.class org/apache/chemistry/opencmis/server/support/filter/LoggingFilter$LoggingResponseWrapper.class org/apache/chemistry/opencmis/server/support/filter/LoggingFilter.class org/apache/chemistry/opencmis/server/support/query/AbstractPredicateWalker.class org/apache/chemistry/opencmis/server/support/query/CalendarHelper.class ..... com/opentext/ com/opentext/connectors/ com/opentext/connectors/msexchangeonlinegraph/ com/opentext/connectors/msexchangeonlinegraph/annotations/ com/opentext/connectors/msexchangeonlinegraph/cmis/ com/opentext/connectors/msexchangeonlinegraph/cmis/apiutils/ com/opentext/connectors/msexchangeonlinegraph/cmis/domain/ com/opentext/connectors/msexchangeonlinegraph/cmis/impl/ com/opentext/connectors/msexchangeonlinegraph/cmis/objects/ com/opentext/connectors/msexchangeonlinegraph/cmis/typedef/ com/opentext/connectors/msexchangeonlinegraph/cmis/utils/ com/opentext/connectors/msexchangeonlinegraph/annotations/ConnectorCmisService.class com/opentext/connectors/msexchangeonlinegraph/cmis/apiutils/CommonApi.class com/opentext/connectors/msexchangeonlinegraph/cmis/apiutils/ConversationContainer.class com/opentext/connectors/msexchangeonlinegraph/cmis/apiutils/FolderContainer.class com/opentext/connectors/msexchangeonlinegraph/cmis/apiutils/ICmisChildContainer.class com/opentext/connectors/msexchangeonlinegraph/cmis/apiutils/MessageContainer.class com/opentext/connectors/msexchangeonlinegraph/cmis/apiutils/RootContainer.class com/opentext/connectors/msexchangeonlinegraph/cmis/apiutils/UserContainer.class com/opentext/connectors/msexchangeonlinegraph/cmis/domain/Bearer.class com/opentext/connectors/msexchangeonlinegraph/cmis/domain/Body.class com/opentext/connectors/msexchangeonlinegraph/cmis/domain/DirectoryRole.class com/opentext/connectors/msexchangeonlinegraph/cmis/domain/DirectoryRoles.class ...

One Jar Maven Plugin

An alternative method for generating an executable jar is the One Jar project.

This offers a specialized class loader that is capable of loading resources such as classes from the containers inside a ZIP file, rather than using jars located in the directory.

  • Advantages of the One Jar include a well-organized delegation architecture, the ability to have subclasses at the highest level, support for outside jars, and the capability of supporting Native libraries.
  • The disadvantage is that it is no longer receiving continuous assistance until 2012

Spring Boot Maven Plugin

To repackage your application, all you need to do is include a reference to the plugin in your pom.xml file. This Maven build jar without dependencies plugin offers a unified way to create, package, and organize Spring Boot apps straightaway via your Maven project.

A Simple Application

Begin by clearly articulating the intended objective and operational capabilities of the application. It might potentially function as a task manager, a weather application, or a budget tracker. Subsequently, choose the suitable programming language and tools for your project. Depending on your objectives and proficiency, you have the option to use programming languages such as Python, JavaScript, or Swift. Create a user-centric interface that is easy to use and aesthetically pleasing. Develop the essential features and functions, including data input, storage, and retrieval.

Including Maven Assembly Plugin

The Maven Assembly Plugin is a powerful tool that enables you to generate personalized distribution packages from your Maven project. With the utilization of this plugin, you can effortlessly bundle together the dependencies, resources, and configuration files of your project into a solitary archive that can be disseminated and executed autonomously.

Pre-defined Goals and Descriptors

The assembly plugin has two objectives:

  • Help: presents help documentation for the maven-assembly-plugin.
  • A single package refers to the process of bundling a software bundle or distribution using assembly descriptors.

The plugin depends on the specified descriptors to govern the execution and packaging of the project. While it is possible to generate our descriptions for customized packaging, the system offers the following pre-set descriptors as defaults:

1. The "bin" command generates a binary JAR file by executing the "mvn package" command and includes any README, LICENSE, and NOTICE files found in the project's root directory.

2. The "jar-with-dependencies" option generates a JAR file that includes the compiled output of your project, as well as its unpacked dependencies.

3. The "src" command packages the contents of the project's "/src" directory structure.

4. The project generates an assembly that includes all components of the project, except any build product located in the /target directory.

POM Changes

We use the descriptor jar-with-dependencies to generate a unified package including all built resources. Furthermore, we have included the MainClass classpath as a Manifest item. The primary () function of this jar file will be run when it is executed from the command line.

Default Packaging

To build and package the project as a fat jar, use the Maven package command in the root folder of the project.

The command "mvn clean package" is used to clean and package a Maven project.

The command will generate two jar files in the /target directory:

The file is named executable-jar-demo-1.0-SNAPSHOT.jar. This is a lightweight container that does not include its required dependencies. By using this jar, it will automatically scan the classpath for any required dependencies.

The name of the executable jar file is “executable-jar-demo-1.0-SNAPSHOT-jar-with-dependencies” This is a comprehensive jar file that contains all the necessary classes and dependencies. The execution of this jar file is possible on any machine that has Java installed.

Executable JAR Demo

Custom Packaging

The resulting file name includes the assembly ID, which might be preferred in some situations. We have the option to change it to an incorrect value.

<configuration> <appendAssemblyId>false</appendAssemblyId> ... ... </configuration>

Fat JAR POM Configuration

In order to generate a Fat JAR from your project using the maven build fat jar, you need to add a Fat JAR build setting to your project's POM file. To enable the creation of a Fat JAR from your project, you need to include the maven-assembly-plugin in the plugin section of your POM file in the Maven configuration. Maven uses the term "assembly" to refer to the output product that it creates. Therefore, the plugin is named maven-assembly-plugin. Below is an extract from a POM file that demonstrates the setup of the maven-assembly-plugin:

<build> <finalName>my-project-name</finalName> <plugins> <!-- other Maven plugins ... --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.1</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>

The configuration XML element inside the maven-assembly-plugin configuration includes the descriptorRef, which specifies the kind of assembly that this configuration should create. The Maven parameter "jar-with-dependencies" instructs Maven to create a JAR file that includes all its dependencies, often known as a Fat JAR.

The act of carrying out capital punishment The XML element specifies the Maven build phase and objective at which this Maven plugin should be performed. The maven-assembly-plugin must be invoked only during the package phase.

Maven Command to Build Fat JAR

The Maven command to generate a Fat JAR for your project is:

Execute the command "mvn clean package".

While the Maven package stage is executed with the maven-assembly-plugin configuration provided previously, Maven will construct a Fat JAR in the target directory. This Fat JAR will include each of Maven's other building merchandise, such as implemented classes and generated JavaDocs. The Fat JAR will be named in the following manner:

The name of my project's executable JAR file, including all its dependencies, is "my-project-name-jar-with-dependencies.jar".

Full POM File With Fat JAR Configuration

Below is a complete Maven POM file that includes a configuration for a Fat JAR. This example is provided to demonstrate the structure and content of such a POM file:

<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>com.jenkov.myprojectname</groupId> <artifactId>my-project-name</artifactId> <version>1.1.0</version> <packaging>jar</packaging> <name>My Project Name</name> <dependencies> <!-- Dependencies used by project --> </dependencies> <build> <finalName>my-project-name</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.1</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>

Configure the Assembly plugin

Before constructing an assembly, it is necessary to first setup the Assembly plugin.

Locate the pom.xml file and verify that the main app class is stated:

<properties> <main.class>com.example.ApplicationKt</main.class> </properties>

If you use EngineMain without the explicit main() function, the application's main class depends on the used engine and might look as follows: io.ktor.server.netty.EngineMain.

Add the maven-assembly-plugin to the plugins block as follows:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.6</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>${main.class}</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>assemble-all</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>

Build an assembly

To construct an assembly for the program, use the interface and perform the following command:

Execute the command "mvn package".

This action will generate a fresh destination directory for the assembly, which will encompass the .jar files.

Run the application

To execute the constructed program, according to the instructions provided:

To execute the program, open a new terminal window and use the java -jar command.

The example project appears as follows:

Execute the Java program by using the command "java -jar target/tutorial-server-get-started-maven-0.0.1-jar-with-dependencies.jar".

Upon successful execution of your application, a confirmation message will be shown.

[main] INFO Application - The application is responding at the following address: http://0.0.0.0:8080

How does a Fat JAR work?

  • A Fat JAR is a consolidated JAR file that contains all the necessary dependencies for a Java program to execute.
  • When a Java program launches, the runtime system retrieves the class files and files via the Fat JAR and any associated package.
  • The construction of a Fat JAR entails the help of a creation tool to gather all the dependencies and consolidate them into a solitary JAR file.

Benefits of using Maven Build Fat JAR

1. Portability

With the help of the installation of Java, a FAT JAR can operate with ease. You are not required to incorporate any extra reliance. As a result, it makes it convenient to make use of applications of Java in various environments and mediums.

2. Improved Performance

Loading several jar files can be at a rapid speed as compared to loading files from a FAT JAR. As the reliances are situated in one file, loading will be easy. This will improve the performance of a Java application. Applications that have reliances in large numbers can have enhanced applications.

3. Simplified management of dependencies

It is essential to know that a FAT JAR has the requisite reliance to keep reliances separately. Users need not be concerned about the trifles in regards to the version. By doing so, you can minimize the errors that are caused due to discrepancies in reliances.

Comparison table for Maven plugins

PluginFlexibilityPackage relocationCustom classloader
AssemblyHighNoNo
ShadeHighYesNo
OnejarLowNoYes

Non-maven jars in your project

To do this, you need to establish a directory within your Java module that functions as a maven repository, which you may reference using the project's ${basedir} property. When integrating non-Maven JARs into the project, it is crucial to verify interoperability and address any potential version issues.

Building a fat jar & making it executable

The document that may be used to determine this combination wherein:

To create a fat jar, use the Maven Assembly Plugin.

To execute the program, use the Maven Archiver.

It seems that the arrangement of elements in the Maven configuration file may need to be adjusted based on the versions of the archiver and Assembly plugin being used. If you are using JDK 1.6, further parameters are required. I achieved success by taking the next steps:

<build> <plugins> <plugin> <!-- NOTE: We don't need a groupId specification because the group is org.apache.maven.plugins ...which is assumed by default. --> <artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-4</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>be.jedi.jvncsender.VncSenderMain</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- append to the packaging phase. --> <goals> <goal>single</goal> <!-- goals == mojos --> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> </project>

Conclusion:

In the current content we learned what is the fat jar, its uses, how to create fat jar file in different ways.

Related article

Spring Cloud Config provides server and client modules for supporting externalized Configuration in a distributed system.

Microservices have become one of the enablers in the digital transformation journey as it is always focused and built on Business Need" and Single Responsibility. Microservices pattern enables scalability, speed, efficiency, and agility because of De-centralized API.

Layers of docker file just like, files are generated after running some command. Docker provides the different storage drivers for Linux flavored operating systems and windows.

DMCA Logo do not copy