Skip to content

/commands/java/create-executable-jar

jar --create --main-class: create an executable JAR and run it with java -jar

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · openjdk version "17.0.20.1" 2026-08-18updated
tool
Java
versions
Java 9+ (--create, --main-class), jar cfe: Java 6+
os
linux, macos, windows

jar --create --file app.jar --main-class com.example.App -C out . packs the compiled classes in out/ into app.jar and writes a manifest with Main-Class: com.example.App. Then java -jar app.jar starts that class. The short, older form of the same command is jar cfe app.jar com.example.App -C out ..

Build and run an executable JAR

bash
mkdir -p src/com/example
cat > src/com/example/App.java <<'EOF'
package com.example;

public class App {
    public static void main(String[] args) {
        System.out.println("running from " + App.class.getProtectionDomain().getCodeSource().getLocation().getPath().replaceAll(".*/", ""));
        System.out.println("args: " + String.join(" ", args));
    }
}
EOF
javac -d out src/com/example/App.java
jar --create --file app.jar --main-class com.example.App -C out .
jar --list --file app.jar
mkdir check && cd check && jar --extract --file ../app.jar META-INF/MANIFEST.MF && cd ..
grep Main-Class check/META-INF/MANIFEST.MF | tr -d '
'
java -jar app.jar one two

Output

META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/App.class
Main-Class: com.example.App
running from app.jar
args: one two

-C out . changes into out/ and adds everything there, so the JAR holds com/example/App.class at the right path. Arguments after the JAR file name go to main. Manifest lines end with CR LF, which is why tr strips the carriage return before printing.

Without a Main-Class

A JAR made without --main-class cannot be started with java -jar:

bash
mkdir -p out/com/example
echo 'package com.example; public class App { public static void main(String[] a) { System.out.println("ok"); } }' > App.java
javac -d out App.java
jar --create --file plain.jar -C out .
java -cp plain.jar com.example.App
java -jar plain.jar

Output · exit 1

ok
no main manifest attribute, in plain.jar

Running the class explicitly with -cp still works; -jar needs the manifest entry and otherwise stops with no main manifest attribute, in plain.jar and exit status 1.

jar options

CommandWhat it does
jar --create --file app.jar --main-class X -C out .Create an executable JAR from the out folder
jar cfe app.jar X -C out .Same with the short options (c create, f file, e entry point)
jar --create --file app.jar --manifest manifest.txt -C out .Use your own manifest lines, for example Class-Path
jar --list --file app.jar (jar tf app.jar)List the entries
jar --update --file app.jar --main-class XAdd or change the entry point of an existing JAR
jar --describe-module --file app.jarShow module information of a modular JAR

Dependencies with Class-Path

When the program needs other JARs, add a Class-Path line to the manifest. The entries are relative URLs separated by spaces, resolved from the folder of the JAR:

manifest.txt
Class-Path: lib/greeter.jar lib/json.jar

Create the JAR with --manifest manifest.txt (the file must end with a newline, or the last line is ignored) and ship the lib/ folder next to it.

Pitfalls

  • Could not find or load main class from java -jar means the Main-Class value does not match a class inside the JAR, often because -C was missing and the classes were stored under out/com/....
  • UnsupportedClassVersionError on another machine means the JAR was compiled for a newer Java; compile with javac --release N for the oldest Java you support.
  • -cp is ignored when you use -jar; put dependencies in the manifest instead.

Confirm it worked

jar --list --file app.jar shows the class files at their package paths and META-INF/MANIFEST.MF; java -jar app.jar runs without extra arguments.

FAQ

What does no main manifest attribute mean?

The JAR's META-INF/MANIFEST.MF has no Main-Class entry, so java -jar does not know which class to start. Rebuild it with --main-class (or e in jar cfe), or run a class directly with java -cp app.jar com.example.App.

Does java -jar use my -cp or CLASSPATH?

No. With -jar, the JAR is the only class path entry, plus the Class-Path attribute of its manifest. -cp and the CLASSPATH variable are ignored.

How do I include dependencies in one JAR?

The jar tool cannot merge other JARs into yours. Either list them in the manifest Class-Path and ship them next to the JAR, or build a fat JAR with a build tool plugin such as the Maven Shade plugin or the Gradle Shadow plugin.

Sources