skip to content

JAR & Manifest

maven-jar-plugin and the MANIFEST.MF entries it writes, including Main-Class, Class-Path, and multi-release markers. Asked when an interviewer wants to know exactly what makes a plain jar runnable.

on this pageshow

explore

questions

5

What is the MANIFEST.MF file inside a JAR, and how does Maven create it for you?

level: juniorimportance: must knowfreq 60%

answer

  1. META-INF/MANIFEST.MF
  2. Name: value headers
  3. maven-jar-plugin at package phase
  4. <archive> config block
  5. Manifest-Version + Created-By defaults

basics

~10 s

MANIFEST.MF lives in META-INF/ inside a JAR and holds metadata as key: value lines (like the entry-point class). The maven-jar-plugin generates it automatically when you build with packaging jar.

solid answer

~30 s

Every JAR contains a META-INF/MANIFEST.MF file: plain text, one "Name: value" header per line, that the JVM and tooling read for metadata. When your project uses <packaging>jar</packaging>, the maven-jar-plugin runs at the package phase and writes this file. By default it adds Manifest-Version, Created-By, and Build-Jdk-Spec. You can extend it via the plugin's <configuration><archive> block: <manifest> controls generated headers (mainClass, addClasspath, addDefaultImplementationEntries) and <manifestEntries> lets you add arbitrary custom headers. The manifest is what makes a JAR runnable (Main-Class), declares a classpath (Class-Path), or carries version info (Implementation-Version).

code

bash · 2 lines
bash
mvn package
unzip -p target/app.jar META-INF/MANIFEST.MF

go deeper

for a junior

Know it lives in META-INF, is key:value text, and Maven writes it for jar packaging.

for a middle

Know the <archive> config block with <manifest> vs <manifestEntries> and how to inspect the output.

for a senior

Know which headers are auto-generated vs manual, and the package-phase binding of maven-jar-plugin.

for a principal

Standardize manifest metadata (build provenance, version headers) across modules via a parent pom and shared plugin management.

## What a JAR and its manifest are A **JAR** (Java ARchive) is just a ZIP file with a `.jar` extension that bundles compiled `.class` files and resources. Inside, a special folder named `META-INF` holds metadata. The most important metadata file is **`META-INF/MANIFEST.MF`** — a plain-text file the Java runtime and build tools read. ## Manifest format The manifest is a list of **headers**, one per line, in the form `Name: value` (note the mandatory single space after the colon). Lines longer than 72 bytes are wrapped. A blank line separates the *main* section from optional *per-entry* sections. Example main section: ``` Manifest-Version: 1.0 Created-By: Apache Maven 3.9.6 Build-Jdk-Spec: 17 Main-Class: com.example.App ``` ## How Maven produces it When your `pom.xml` declares `<packaging>jar</packaging>` (the default), Maven binds the **maven-jar-plugin**'s `jar:jar` goal to the **package** phase. That plugin builds the archive and writes the manifest. You don't list the plugin explicitly unless you want to configure it. You customize the manifest through the plugin's `<configuration>` → `<archive>` element: - `<manifest>` — toggles *generated* headers: `<mainClass>`, `<addClasspath>`, `<addDefaultImplementationEntries>`, etc. - `<manifestEntries>` — free-form custom headers you type yourself. - `<manifestFile>` — point to a hand-written manifest to merge in. ## Worked pom snippet ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.example.App</mainClass> </manifest> <manifestEntries> <Built-By>ci-server</Built-By> </manifestEntries> </archive> </configuration> </plugin> </plugins> </build> ``` After `mvn package`, inspect it with `unzip -p target/app.jar META-INF/MANIFEST.MF`. ## Why it matters The manifest is how a JAR declares its **entry point** (`Main-Class`), an external **classpath** (`Class-Path`), **version/vendor** info (`Implementation-*`), and advanced features like **Multi-Release** JARs. Without it the JVM cannot `java -jar` your archive.

  • Which Maven phase writes the manifest, and via which plugin/goal?
    The package phase, via the maven-jar-plugin's jar:jar goal, which is bound by default for jar packaging.
  • Name two headers Maven adds to the manifest by default.
    Manifest-Version and Created-By (also Build-Jdk-Spec); none of the Implementation-* or Main-Class headers appear unless configured.

The manifest is like the label on a shipping box: it doesn't change the contents, but it tells the handler what's inside, who sent it, and where it should go (which class to run).

saying these in an interview costs you the question

  • Saying the manifest stores your actual code or dependencies (it stores only metadata/headers)
  • Thinking you must always declare maven-jar-plugin explicitly — it's bound by default for jar packaging
  • Confusing META-INF/MANIFEST.MF with a properties file (colon-space format, not = )

context

open as a page

How do you make a JAR runnable with `java -jar` and how does the Class-Path header relate to dependencies?

level: middleimportance: must knowfreq 65%

basics

~10 s

Set <mainClass> under <archive><manifest> so Maven writes Main-Class to the manifest; then java -jar works. Add <addClasspath>true</addClasspath> to write a Class-Path header pointing at dependency JARs.

open as a page

What do addDefaultImplementationEntries / addDefaultSpecificationEntries do, and what Implementation-* headers result?

level: middleimportance: should knowfreq 40%

basics

~10 s

Setting <addDefaultImplementationEntries>true</addDefaultImplementationEntries> tells maven-jar-plugin to write Implementation-Title/Version/Vendor headers from your pom's name, version, and organization, so code can read its own version at runtime.

open as a page

How do you add arbitrary custom manifest headers, and what happens when they collide with generated or hand-written ones?

level: seniorimportance: should knowfreq 28%

basics

~10 s

Add free-form headers under <archive><manifestEntries>, each child element name becoming a header. You can also merge a hand-written file via <manifestFile>. manifestEntries values take precedence over generated defaults.

open as a page

What is a Multi-Release JAR, how do you build one with Maven, and what does the manifest contain?

level: seniorimportance: should knowfreq 30%

basics

~10 s

A Multi-Release JAR ships one base set of classes plus version-specific overrides under META-INF/versions/<N>/. Its manifest has Multi-Release: true, so a JDK 17 runtime prefers versions/17 classes over the base.

open as a page