ByteScope

Java JAR file format

A Java Archive — a ZIP bundling compiled .class files and a manifest.

MIME type
application/java-archive
Extensions
.jar
Category
Archives & compression

Magic-number signature

0x00000000504B0304PK··'PK' — it is a ZIP

Inside the ZIP: 'META-INF/MANIFEST.MF' plus one or more '.class' entries.

About the Java JAR format

A JAR is a ZIP with one convention layered on top: a META-INF directory whose MANIFEST.MF describes the archive — the main class for an executable JAR, the class path, the module name, and, in a signed JAR, a digest for every entry. Nothing else about the ZIP changes, which is why any archive tool can open a JAR and why the format has been reused for WARs, EARs, Spring Boot fat JARs and, historically, Android APKs. The catch is that the convention includes entry order: streaming readers look for the manifest at the very front and give up quickly if it is not there.

Header layout, byte by byte

OffsetLengthFieldMeaning
04Local file header signature50 4B 03 04. A JAR is a ZIP byte for byte; nothing at offset 0 mentions Java. Every entry starts with one of these, and only the first is at a fixed position.
42Version needed to extract10 for a stored entry, 20 for deflate — and the first entry of a JAR written by the jar tool is the directory META-INF/, which is stored, so this field commonly reads 10 in a file whose real contents are all deflated.
62General purpose bit flag0x0800 (bit 11) marks the entry name UTF-8, which the JDK's jar tool sets. Bit 3, the streaming flag that pushes sizes after the data, appears in JARs produced by servers that generate them on the fly.
82Compression method0 stored, 8 deflate. Directory entries such as META-INF/ are stored with zero length, which is why a JAR's first entry often has a CRC and both sizes of zero without anything being wrong.
104Last modified time and dateMS-DOS packed time at 10 and date at 12: two-second resolution, no time zone, nothing before 1980. Reproducible builds pin these to a constant, which is why so many JARs claim to be from 1980-01-01 or 2010-01-01.
144CRC-32CRC-32 of the uncompressed entry, with the compressed size at 18 and the uncompressed size at 22. In a signed JAR these are independent of the SHA digests in META-INF, so an entry can pass its CRC and still fail signature verification.
262File name lengthByte length of the name at offset 30. For a JAR written by the jar tool this is 9 — the length of META-INF/ — which is a quick, if informal, tell in a hex dump.
30variableFirst entry nameWhere a JAR announces itself in practice: META-INF/ followed by META-INF/MANIFEST.MF. The order is not decorative, because a streaming reader only looks at the front of the file for the manifest.
-224End of central directory signature50 4B 05 06, exactly 22 bytes from the end with no archive comment. The class loader reads the central directory from here, which is why it can load one class out of a 60 MB JAR without decompressing the rest.
-64Offset of the central directoryStart of the central directory, measured from the beginning of the file. A self-extracting or executable JAR with a shell script prepended still works because readers tolerate the shift, but the value here no longer matches the raw file layout.

Telling it apart from its neighbours

Easily confused withHow to tell
ZIPIdentical at byte level. What makes a ZIP a JAR is META-INF/MANIFEST.MF in the central directory, plus normally .class entries. Renaming a JAR to .zip changes nothing; renaming a ZIP to .jar produces a file java -jar rejects for having no main manifest attribute.
Android APKAn APK began life as a JAR and still has META-INF, so the two look alike in an archive viewer. The separator is content: .dex entries and AndroidManifest.xml mean APK, .class entries and MANIFEST.MF alone mean JAR, and only an APK carries the 'APK Sig Block 42' magic before its central directory.
war / earSame format, different required layout: a WAR keeps its classes under WEB-INF/classes and its libraries under WEB-INF/lib, an EAR holds application.xml plus other archives. A servlet container reads the layout, not the extension, so a misnamed WAR fails on a missing WEB-INF rather than on anything about the ZIP.
Spring Boot jarA runnable JAR whose own classes live under BOOT-INF/classes and whose dependencies are nested JARs under BOOT-INF/lib, with a launcher named in MANIFEST.MF as the real Main-Class. It opens as an ordinary JAR, but its application classes are not where a class loader would normally look, which is why extracting one and running the main class directly does not work.

How these files break

  • The manifest is no longer at the front. Rebuilding a JAR with a general-purpose ZIP tool preserves every byte of content and loses the ordering, and a streaming reader then reports no manifest at all. Measured here with the JDK's own API: a JAR written by the jar tool (META-INF/ then META-INF/MANIFEST.MF) returned the manifest, while archives with the manifest as the second and third entry after a class file both returned null. java -jar still ran them, because it reads the central directory rather than streaming — so the same file works one way and fails the other.
  • Truncated tail. Every local header survives and the file looks healthy from offset 0, but the end of central directory record is gone and the class loader, which starts from the end, cannot list a single entry. Recovery means scanning forward for 50 4B 03 04 and rebuilding the directory.
  • Broken signatures after repackaging. A signed JAR stores a digest for every entry in META-INF/MANIFEST.MF and a signature file beside it, so shading, re-compressing or merging changes the digests and the JVM refuses the archive with a security exception rather than a corruption message.
  • Duplicate entries from a naive merge. Concatenating dependencies into one archive can produce two entries with the same path; ZIP permits it and the class loader takes the first, so which version of a class wins depends on the order in the central directory — a real file with an invisible defect.

Where the format stands today

The JAR is the unit of distribution for the entire JVM ecosystem: everything on Maven Central is a JAR, every dependency a build tool resolves is a JAR, and every server-side Java application ships as one, whether as a plain library, a WAR for a container or a self-contained Spring Boot archive. Nothing has replaced it — the module system added module-info.class inside the JAR rather than a new container, and native-image and jlink produce executables from JARs instead of replacing them upstream. Where it has lost ground is client-side delivery: applets are gone and Java Web Start with them, so a JAR today is a server or build-time artefact. Its enduring advantage is the ZIP central directory, which lets a class loader pull one class out of thousands without touching the rest.

Open Java JAR files on this site

Every one of these runs in your browser — the file never leaves your machine.

Related formats

Formats that are easy to confuse with Java JAR — compare their leading bytes.

FormatFirst bytesExtension
ZIP50 4B 03 04.zip
Android APK50 4B 03 04.apk
Java class fileCA FE BA BE.class

Frequently asked questions

What is a magic number in a file?

The first few bytes of a file, which identify its format regardless of what the name says. A PNG always starts with 89 50 4E 47; a ZIP with 50 4B 03 04. Operating systems, browsers and the file command all read these bytes rather than trusting the extension, which is why renaming a file does not change what it actually is.

How do I check a file's magic number myself?

On macOS or Linux, xxd -l 16 yourfile prints the first 16 bytes; on Windows, Format-Hex -Path yourfile -Count 16 in PowerShell. Or drop the file into the File Type Identifier on this site, which reads the bytes locally and names the format for you — nothing is uploaded.

Why do two formats share the same magic number?

Because one is built on the other. Every docx, xlsx, pptx, apk, jar and epub begins with the ZIP signature, since all of them are ZIP archives underneath; telling them apart means looking at the entries inside. Java class files and macOS universal binaries both start with CA FE BA BE and are distinguished by the field that follows.

Can a file have no magic number at all?

Yes. Text-based formats — XML, HTML, JSON, SVG, CSV — have no fixed byte signature, so they are recognized structurally instead: a leading <?xml declaration, a <svg element, or a { followed by a quoted key. That detection is a good guess rather than a certainty, which is why this reference marks those formats as probe-detected.

Does a matching magic number mean the file is safe?

No. It tells you what the format is, not whether the contents are harmless — a genuine PDF or docx can still carry a malicious payload. Identifying the true type is a useful first check, especially when the extension disagrees with the bytes, but it is not a malware scan.

Have a file that might be in the Java JAR format? Identify it with the File Type Identifier — it reads the magic number locally, nothing is uploaded. Or browse all formats.