last modified July 6, 2024
In this article we show how to work with JAR files in Java.
A JAR file serves as a logical container that bundles all the essential
components of a Java software application or library into a single compressed
file. These components include Java class files, associated metadata, and
resources. JAR files use lossless compression algorithms, making them efficient
for storage and easy to share. They are based on the ZIP format and commonly
have a .jar file extension.
JAR stands for Java ARchive. It's a file format used to aggregate many files,
primarily .class files (compiled Java code), and other resources
(text files, images, etc.) into a single archive.
The key characteristics of JAR files are:
There are two types of JAR files:
java -jar command.
Follow these steps to create a JAR file in IntelliJ IDEA. Select:
The Maven Shade Plugin packages our Java project into an uber-jar that includes both main artifact and its dependencies. It simplifies deployment by creating a single JAR file containing everything needed for our application. Additionally, it can rename packages to prevent conflicts between dependencies. It is used during the package phase in our Maven build process.
The shaded JAR can be made executable, allowing you to run our application directly from the generated JAR file.
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.6.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration>a <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>com.zetcode.Main</Main-Class> <Build-Number>1.0</Build-Number> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
This is an example of a Maven shade plugin being configured. It is made
executable with a main class pointing to com.zetcode.Main
This is the default Gradle task for creating a JAR archive. It packages our compiled class files (*.class) and resources from our project into a single JAR file.
It does not include any dependencies in the JAR. Our application needs the libraries it depends on to be installed separately on the target system.
plugins {
id 'java'
id 'application'
}
group = 'com.zetcode'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
application {
mainClass = 'com.zetcode.Main'
}
jar {
duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
manifest {
attributes(
'Main-Class': 'com.zetcode.Main'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
It creates a fat JAR or shadow JAR, which is a single JAR containing our application code and all its transitive dependencies.
It makes deployment easier as you only need to distribute the single JAR file containing everything our application needs. The JAR file will be larger due to the inclusion of all dependencies.
plugins {
id 'java'
id 'application'
id 'io.github.goooler.shadow' version '8.1.8'
}
group = 'com.zetcode'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
application {
mainClass = 'com.zetcode.Main'
}
dependencies {
implementation 'org.eclipse.collections:eclipse-collections:11.1.0'
}
jar {
// duplicatesStrategy = DuplicatesStrategy.EXCLUDE
duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
manifest {
attributes(
'Main-Class': 'com.zetcode.Main'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
We create an executable fat JAR file that uses the Eclipse collections library.
It consists of two JAR files: eclipse-collections-11.1.0.jar and
eclipse-collections-api-11.1.0.jar. These two files must be
included in the final JAR as well.
bin manifest.txt lib eclipse-collections-11.1.0.jar eclipse-collections-api-11.1.0.jar src └───main └───java └───com └───zetcode Main.java
At the beginning, the project directory looks like this.
package com.zetcode;
import org.eclipse.collections.api.factory.Lists;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> words = Lists.mutable.of("sky", "town", "rock");
words.add("ten");
words.add("small");
words.add("lucid");
System.out.println(words);
}
}
We define a list of words using Lists.mutable.of. This method
comes from the Eclipse collections library.
We compile the program with javac tool. We need to provide the
path to the libraries with the -cp option.
javac -cp lib\eclipse-collections-11.1.0.jar;lib\eclipse-collections-api-11.1.0.jar src\main\java\com\zetcode\Main.java -d bin
The Java bytecode is generated in the bin directory. On Windows, we
separate libraries with semicolon character. We use a colon on Unix systems.
java -cp bin;lib\eclipse-collections-11.1.0.jar;lib\eclipse-collections-api-11.1.0.jar com.zetcode.Main
We run the program with java tool.
The manifest.txt file:
Manifest-Version: 1.0 Main-Class: com.zetcode.Main Class-Path: ../lib/eclipse-collections-11.1.0.jar ../lib/eclipse-collections-api-11.1.0.jar
In the manifest.txt file, we specify the main class and the class
path. In the class path, we include the two libraries that we use in the
program. We place the manifest.txt file into the bin
subdirectory, where we generate the fat JAR file.
Note that the last empty line is mandatory.
jar -cvfm main.jar manifest.txt com ../lib added manifest adding: com/(in = 0) (out= 0)(stored 0%) adding: com/zetcode/(in = 0) (out= 0)(stored 0%) adding: com/zetcode/Main.class(in = 901) (out= 513)(deflated 43%) adding: lib/(in = 0) (out= 0)(stored 0%) adding: lib/eclipse-collections-11.1.0.jar(in = 10475509) (out= 9523556)(deflated 9%) adding: lib/eclipse-collections-api-11.1.0.jar(in = 1789461) (out= 1388818)(deflated 22%) adding: lib/package.md(in = 7625) (out= 2496)(deflated 67%) adding: lib/slf4j-api-1.7.36.jar(in = 41125) (out= 36381)(deflated 11%) adding: lib/sqlite-jdbc-3.46.0.1-20240611.065717-6.jar(in = 13615977) (out= 13580269)(deflated 0%)
Inside the bin directory, we create the JAR file.
java -jar main.jar [sky, town, rock, ten, small, lucid]
Finally, we run the JAR file.
In this article we have worked with JAR files in Java.
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Java tutorials.