JAR File Explained (A ZIP With a Manifest Java Actually Reads)

Why a .jar file opens fine in any ZIP tool, but only the JVM cares about the META-INF/MANIFEST.MF file sitting inside it.

  1. Add a file Choose or drop it here
  2. Pick the format Change it whenever needed
  3. Download the result After conversion completes

A JAR Is Literally a ZIP File With One Required Extra Piece

A .jar (Java ARchive) file is, at the byte level, a ZIP file — Sun Microsystems built the JAR format around PKWARE's existing ZIP container in 1997 rather than inventing a new one, so the same local headers, compressed data, and central directory structure that any ZIP tool understands are exactly what a JAR contains. The proof of this is trivial and well documented: renaming a .jar file's extension to .zip lets any ordinary ZIP utility open and browse it without complaint, because there's genuinely nothing ZIP-incompatible about it.

What makes a JAR a JAR, rather than just a ZIP with Java code in it, is one specific required entry: META-INF/MANIFEST.MF. The JAR specification requires this file to exist as part of the archive's META-INF directory, and it's what the Java Virtual Machine (JVM) actually reads to figure out how to treat the archive — whether it's a plain library to add to a classpath, or an executable program with a defined entry point.


What the Manifest File Actually Tells the JVM to Do

META-INF/MANIFEST.MF is a plain-text file of key-value pairs called headers, grouped into sections. The most consequential header for everyday use is Main-Class, which names the specific class containing the public static void main method the JVM should run when the JAR is executed directly with a command like java -jar app.jar. Without a Main-Class header present, attempting to run the JAR this way produces Java's well-known "no main manifest attribute" error — the JAR isn't broken, it's just missing the one line of metadata that tells Java where to start.

A second commonly used header is Class-Path, which lists other JAR files the archive depends on at runtime, letting one JAR reference classes that live in separate JAR files without the JVM needing to be told about them separately on the command line. Since Java 9, JAR files can also be "multi-release," using a special META-INF/versions/ directory structure that lets a single JAR contain different versions of the same class compiled for different Java releases, with the JVM automatically picking the version matching whatever Java release is actually running it.

The manifest can also record simpler bookkeeping headers that have nothing to do with execution at all — Manifest-Version, which states which version of the manifest format the file follows, and Created-By, which typically records which JDK build produced the archive. None of these affect how the JAR runs; they exist purely as metadata a build tool or developer might want to inspect later, and their presence or absence has no bearing on whether the archive executes correctly.


What a JAR Carries That a Plain ZIP of the Same Files Wouldn't

  • Gain — a defined entry point: the Main-Class header in MANIFEST.MF is what lets java -jar know which class to run, something a plain ZIP of the same .class files has no equivalent for.
  • Gain, if signed — cryptographic proof of origin: jarsigner adds a META-INF/*.SF signature file and a *.RSA (or *.DSA/*.EC) signature block containing a certificate chain, letting the JVM verify the archive hasn't been tampered with since signing.
  • Lose, the moment the archive is modified after signing — that same signature's validity: changing even one byte of any signed entry breaks the digest match recorded in the manifest, and the JAR then fails signature verification entirely.
  • Gain — classpath dependency declarations: the Class-Path manifest header can point to other JARs the archive needs, information a generic ZIP archive has no standard place to store.
  • Gain, since Java 9 — multi-release class support: the META-INF/versions/ structure lets one JAR serve different class bytecode to different JVM versions automatically.
  • Lose — recognition by the JVM classpath and java -jar, if repacked into a non-ZIP-based format: Java's classloading only understands ZIP-structured archives with a .jar or .zip extension; a 7z, rar, or tar version of the same files isn't a valid classpath entry at all.

Where JAR Signing Actually Breaks and Where It Doesn't

Signing a JAR with Oracle's jarsigner tool computes a cryptographic digest for each file in the archive, stores those digests in the manifest, then creates a signature file (META-INF/ALIAS.SF) containing digests of the manifest's own sections, and finally a binary signature block (META-INF/ALIAS.RSA or .EC) holding the actual signature and the signer's X.509 certificate chain. Any tool that opens the JAR and re-saves it — including simply extracting and re-zipping the same files — invalidates every one of those recorded digests, because the underlying file bytes, timestamps, or compression settings can change even when the visible content looks identical, and jarsigner's verification is byte-exact.

This is documented behavior, not a bug: re-signing a JAR that's already signed requires first deleting the existing .SF and .RSA/.DSA files from META-INF, then running jarsigner again from scratch, since there's no way to layer a second valid signature onto files whose digests no longer match after modification. Any Java-based project that repackages, minifies, or shades a signed dependency JAR has to account for this — the signature simply does not survive being unpacked and rebuilt, regardless of which tool did the repackaging.

Verification itself checks three separate things in sequence: that each entry's digest still matches what the manifest recorded, that the signature file's own digest of the manifest still matches, and that the cryptographic signature in the binary signature block validates against the certificate chain it carries. A failure at any one of those three steps is enough for jarsigner, or the JVM itself at runtime, to report the JAR as unverified, even if the other two checks would have passed.


The Manifest-Related Problems That Actually Show Up in Practice

The single most common complaint tied to JAR files across Java forums and Stack Overflow is the "no main manifest attribute" error when trying to run a JAR built without a Main-Class header — the documented fix is either adding that header manually to MANIFEST.MF and rebuilding the archive, or, in Maven or Gradle projects, configuring the build plugin's manifest section to include the correct main class automatically rather than expecting the tool to guess it.

A second frequent issue involves signed JARs failing verification after a build tool has repackaged them — commonly seen when bundling dependencies into a single "fat" or "uber" JAR — where the fix is either excluding the already-signed dependency's signature files from the merge, or re-signing the final combined JAR after the merge completes, since the original per-dependency signatures cannot survive being merged into a new archive regardless.

A third pattern, useful for troubleshooting rather than a bug, is confirming what's actually inside a JAR's manifest by renaming the file to .zip and extracting it with any ordinary archive tool to read META-INF/MANIFEST.MF directly — a technique repeatedly recommended in Java troubleshooting guides specifically because the JAR format's ZIP compatibility makes it work without any Java-specific tooling at all.


JAR Set Against the Six Archive Formats It Converts Into

Property JAR 7z / rar / tar / tar.gz / tar.bz2 / zip
Container structure ZIP format, plus a required manifest Varies by format; no manifest requirement
Runnable with java -jar Yes, if Main-Class is set No; not a valid Java classpath entry
Digital signature support Yes, via jarsigner (.SF/.RSA files) Varies; not Java-aware if present
Default compression DEFLATE (inherited from ZIP) Varies: DEFLATE, LZMA2, proprietary, or none
Renames cleanly to .zip and opens Yes, always Only zip itself; others need a matching tool
Typical contents Compiled .class files, resources, manifest Any file type

Common Questions About What a .jar File Actually Contains

Is a JAR file just a renamed ZIP file?
Structurally, yes — a JAR uses the exact same ZIP container format. What makes it a JAR specifically is the required META-INF/MANIFEST.MF file, which the JVM reads for Java-specific metadata like the program's entry point.

Why do I get "no main manifest attribute" when running my JAR?
Because the JAR's MANIFEST.MF file has no Main-Class header telling Java which class to run. Adding that header and rebuilding the archive resolves the error.

Can I open a JAR file with a regular ZIP program?
Yes. Since a JAR is a ZIP file internally, renaming it to .zip lets any standard ZIP tool open and browse its contents, including the manifest.

Does re-zipping a signed JAR keep the signature valid?
No. Extracting and re-compressing a signed JAR changes the underlying bytes enough to break the recorded digests in its manifest and signature files, so the archive has to be signed again with jarsigner afterward.

What's the difference between a JAR and a WAR or EAR file?
WAR (Web Application Archive) and EAR (Enterprise Application Archive) are also ZIP-based Java archive formats, following the same underlying structure as JAR but with their own specific directory layouts and manifest conventions for web and enterprise application deployment.