# How to Make a JAR File: A Complete Guide for Java Developers A **JAR file** (Java ARchive) is one of the most practical packaging formats in Java development. It bundles compiled `.class` files, resources, and metadata into a single compressed archive — making it easy to distribute libraries, applications, and plugins. Whether you're packaging your first Java project or automating builds for a larger codebase, understanding how JAR files work and how to create them correctly makes a real difference in how your code runs and travels. ## What Is a JAR File, Exactly? Under the hood, a JAR file is just a **ZIP archive** with a `.jar` extension and a special directory called `META-INF`. Inside that directory lives a file called `MANIFEST.MF`, which stores metadata about the archive — including, optionally, the **main class entry point** that tells the Java runtime which class to execute when you run the JAR. JAR files can be: - **Executable** — runnable directly with `java -jar yourfile.jar` - **Library JARs** — referenced by other projects as dependencies - **Fat JARs (uber JARs)** — bundled with all dependencies included The distinction matters because executable JARs require a properly configured manifest, while library JARs typically don't need one. ## The Core Tool: The `jar` Command The Java Development Kit (**JDK**) ships with a command-line tool simply called `jar`. It's been part of the JDK since Java 1.0 and remains the baseline method for creating JAR files manually. ### Basic JAR Creation Syntax ```bash jar cf output.jar compiled-classes/ ``` The flags break down as: | Flag | Meaning | |------|---------| | `c` | Create a new archive | | `f` | Specify the output filename | | `v` | Verbose output (optional) | | `e` | Set the main class (entry point) | | `m` | Include a custom manifest file | ### Creating an Executable JAR from the Command Line First, compile your Java source files: ```bash javac -d out/ src/com/example/Main.java ``` Then package them into a runnable JAR with an entry point: ```bash jar cfe app.jar com.example.Main -C out/ . ``` The `e` flag sets `com.example.Main` as the `Main-Class` attribute in the manifest automatically. After this, `java -jar app.jar` will launch your application. ### Using a Custom Manifest File If you need more control — setting a **classpath**, adding version metadata, or defining custom attributes — you write your own `MANIFEST.MF`: ``` Manifest-Version: 1.0 Main-Class: com.example.Main Class-Path: lib/dependency.jar ``` ⚠️ The manifest file **must end with a newline**, or the last attribute will be silently ignored by the Java runtime. Package it with: ```bash jar cfm app.jar MANIFEST.MF -C out/ . ``` ## Building JAR Files with Build Tools For any project beyond a single file, using the `jar` command directly becomes unwieldy. Modern Java projects almost universally use build tools that handle compilation, dependency management, and packaging together. ### Apache Maven In a Maven project, running: ```bash mvn package ``` produces a JAR in the `target/` directory automatically, based on your `pom.xml` configuration. To make it executable, you configure the **Maven JAR Plugin** in your POM to specify the main class: ```xml org.apache.maven.plugins maven-jar-plugin com.example.Main ``` For a **fat JAR** that includes all dependencies, the **Maven Shade Plugin** or **Maven Assembly Plugin** handles that bundling step. ### Gradle Gradle projects use a `jar` task built into the Java plugin. A basic executable JAR configuration in `build.gradle` looks like: ```groovy jar { manifest { attributes 'Main-Class': 'com.example.Main' } } ``` Run `gradle jar` (or `./gradlew jar`) and the output lands in `build/libs/`. For fat JARs, the **Shadow Plugin** is the standard Gradle approach. ### IDEs 🛠️ Most Java IDEs — **IntelliJ IDEA**, **Eclipse**, and **NetBeans** — include GUI-based artifact or export wizards that generate JAR files without touching the command line. These tools are convenient for quick one-off exports, though they're generally less reproducible than build tool configurations for team environments. ## Variables That Affect How You Should Build Your JAR Not every approach fits every situation. A few factors shift the right method significantly: - **Project size and complexity** — A single-class utility and a multi-module enterprise application have very different packaging needs. - **Dependency management** — If your code has external dependencies, a simple `jar` command won't include them. You'll need a fat JAR strategy or a proper classpath configuration. - **JDK version** — The `jar` tool syntax evolved with newer JDK versions. JDK 9+ introduced the `--create`, `--file` long-form flags and added support for **multi-release JARs** that target multiple Java versions simultaneously. - **Target environment** — A JAR meant to run as a standalone desktop app, as a server-side library, or inside an application server like Tomcat each has different manifest and classpath requirements. - **Build reproducibility** — If multiple developers or a CI/CD pipeline needs to build the same artifact reliably, a build tool configuration is essential over manual `jar` commands. ## Common Pitfalls to Know About - **Missing or malformed manifest** — Forgetting the trailing newline or misspelling `Main-Class` will cause `java -jar` to fail with an unhelpful error. - **Wrong classpath in the manifest** — Paths in `Class-Path` are relative to the JAR's location at runtime, not the build machine. This trips up many developers when moving JARs between directories. - **Compiling and packaging with mismatched JDK versions** — A JAR compiled targeting Java 17 will not run on a JRE 11 runtime. The `--release` flag in `javac` helps lock the bytecode level deliberately. - **Forgetting resources** — Images, config files, and property files need to be included in the JAR explicitly. Build tools handle this automatically; manual `jar` commands require you to include resource directories yourself. The method that works best — bare `jar` command, Maven, Gradle, or IDE export — depends on where your project sits on the spectrum from quick experiment to production-grade software, and what your build and deployment pipeline already looks like. 🔍