Convert JAR to TAR.GZ Online (Same DEFLATE Algorithm, Applied to a Completely Different Structure)

JAR and gzip both compress with DEFLATE, but a JAR runs it once per file while gzip runs it once over an entire concatenated tar stream — that difference changes how the result behaves, not how well it compresses.

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

JAR and Gzip Share an Algorithm, Not a Structure

This is the one conversion on this site where the compression algorithm doesn't actually change. A JAR compresses each entry with DEFLATE, the algorithm ZIP has used since PKWARE's 1993 specification, and gzip — the compressor behind the .gz half of .tar.gz — also uses DEFLATE internally, standardized in RFC 1952. Converting a JAR's contents into a tar.gz doesn't mean swapping to a different compression method the way converting to 7z (LZMA2) or tar.bz2 (bzip2's Burrows-Wheeler transform) does.

What changes instead is where DEFLATE gets applied. A JAR runs DEFLATE separately on every individual entry, each with its own compressed stream and its own entry in ZIP's central directory. A .tar.gz first concatenates every file and its POSIX metadata into one uncompressed .tar stream, exactly like tar.bz2 does, and only then runs a single DEFLATE pass over that entire combined stream through gzip. Same algorithm, completely different scope — one compressed blob per archive instead of one compressed blob per file.


Why That Scope Difference Still Matters Even With the Same Algorithm

Because ZIP's central directory records the exact byte offset of every entry, a tool can decompress just one file's DEFLATE stream out of a JAR without touching anything else in the archive — extracting META-INF/MANIFEST.MF from a 50 MB JAR costs almost nothing regardless of how many other entries exist. Gzip has no equivalent structure at all; RFC 1952's format defines a single stream with one header and one DEFLATE-compressed body, so a decompressor has no way to skip ahead to a specific file's data. Getting to any one file inside a tar.gz means running gzip's decompression from the very start of the stream through to wherever that file happens to land in the underlying tar layout.

The practical result is that tar.gz behaves like tar.bz2 in this specific respect — no random access to individual files — even though its compression algorithm is identical to what JAR already uses. The format that changes here isn't the compression math; it's whether that math gets boundaries drawn around it per file or applied to one long stream, and that boundary decision is what actually governs how the archive can be used afterward.

RFC 1952 also defines a 10-byte gzip header carrying a fixed two-byte magic number (0x1f 0x8b), a compression method flag, an optional original filename, and a modification timestamp, followed at the very end of the stream by an 8-byte trailer holding a CRC-32 checksum of the uncompressed data and the uncompressed size modulo 2^32. None of that has an equivalent inside a JAR's ZIP structure, where each entry already carries its own CRC-32 in the local header rather than the archive as a whole carrying just one checksum for everything combined.


What Repackaging a JAR as TAR.GZ Gains and Gives Up

  • Lose — per-entry random access: gzip's single-stream RFC 1952 format has no central directory equivalent, so getting to one file means decompressing from the start of the stream, unlike a JAR's independently addressable entries.
  • Lose — recognition by the JVM entirely: java.util.jar and the classloader only work with ZIP-structured containers; a tar.gz stream is never a valid classpath entry or java -jar target, whatever it's named.
  • Lose — jarsigner signature validity: the .SF and signature block digests match the JAR's original per-entry DEFLATE-compressed bytes exactly; rebuilding through tar and a fresh gzip pass produces different bytes and breaks every recorded digest.
  • Gain — POSIX ownership, permission, and symlink metadata: the underlying tar layer records Unix owner, group, and mode bits, and a dedicated symlink entry type, none of which the core JAR/ZIP specification standardizes the same way.
  • Gain, sometimes — a marginally smaller file than plain tar or a per-entry ZIP-style archive: compressing many small, related files as one continuous stream can let DEFLATE's sliding window find repeated patterns across file boundaries that per-entry compression, resetting its window at each file, never gets the chance to see.
  • Lose — the manifest's role as JVM-readable metadata: the manifest's text can still be extracted and read after conversion, but nothing treats its Main-Class or Class-Path headers as functional metadata once the archive stops being a real JAR.

The Tools That Actually Produce a TAR.GZ From JAR Contents

On Linux and macOS, GNU tar's -z flag runs gzip as part of the same command, so tar -czf output.tar.gz -C extracted-jar-contents . handles the tar concatenation and the gzip compression pass together, even though internally they remain the two separate steps described above. Windows has no built-in tar or gzip support in File Explorer, so producing a tar.gz there requires a tool such as 7-Zip, which understands both layers, or running actual GNU tar and gzip inside the Windows Subsystem for Linux.

From Java code, there's no JDK-native way to build a tar.gz either, despite gzip using the same DEFLATE algorithm the JDK's own java.util.zip.Deflater class already implements — that class only writes standalone or ZIP-wrapped DEFLATE streams, not the tar container gzip needs wrapped around it. Apache Commons Compress fills that gap with a TarArchiveOutputStream for the tar layer and java.util.zip.GZIPOutputStream, which is actually included in the JDK, for the gzip layer — meaning the compression half of tar.gz has standard JDK support even though the archiving half doesn't.


The Real Problems Reported With This Specific Conversion

A recurring complaint on build-tooling forums involves someone assuming a tar.gz of JAR contents will compress noticeably better than the original JAR, since both use DEFLATE, then finding the sizes come out nearly identical or the tar.gz is occasionally larger — the explanation is that DEFLATE's compression ratio depends much more on the data itself and the compression level chosen than on whether it's applied per-entry or over one combined stream, so switching structures alone rarely produces a dramatic size change.

A second frequent issue mirrors what happens with tar.bz2: signed JARs archived into tar.gz for long-term storage lose signature validity the moment they're extracted back out, because jarsigner's digests were computed against the JAR's original per-entry compressed bytes, and a full extract-then-recompress cycle through tar and gzip — even using the exact same DEFLATE algorithm — produces different final bytes that no longer match those recorded digests.

A third pattern involves scripts written for one tar.gz creation tool failing against another because of inconsistent handling of the .tar.gz versus .tgz naming convention — some tools require the double extension exactly, while GNU tar's automatic compression-format detection recognizes both interchangeably, and build pipelines that hardcode one convention have reported failures when a teammate's script or CI configuration expects the other.


JAR and TAR.GZ Set Side by Side

Property JAR TAR.GZ
Compression algorithm DEFLATE (ZIP, 1993 spec) DEFLATE (gzip, RFC 1952)
Compression scope Per entry, independently Whole tar stream, as one unit
Extract one file without full decompression Yes, via central directory offset No; sequential decompression required
POSIX permissions and ownership Not part of the core spec Core header fields via the tar layer
JDK-native compression support Yes, java.util.zip Partial; GZIPOutputStream exists, tar layer does not
Java classpath / java -jar support Yes, always No, not recognized at all
Native Windows support Yes, built into Explorer No; needs 7-Zip or WSL

Questions About Turning a JAR Into a TAR.GZ Archive

If JAR and gzip both use DEFLATE, why does converting change anything?
Because the algorithm is applied differently. A JAR compresses each file separately with its own DEFLATE stream and a central directory pointing to it; gzip compresses one continuous concatenated tar stream as a single unit, with no equivalent way to jump to one file's data.

Will my tar.gz be noticeably smaller than the original JAR?
Not necessarily. Since both formats use the same DEFLATE algorithm, the compression ratio depends mainly on the data and compression level, not on switching from per-entry to whole-stream compression, so size differences are often small.

Does a signed JAR's signature survive conversion to tar.gz and back?
No. jarsigner's digests match the JAR's original per-entry compressed bytes exactly. A full extract-and-recompress cycle through tar and gzip produces different bytes, so the signature has to be reapplied with jarsigner afterward regardless of the algorithm involved.

Is .tar.gz the same thing as .tgz?
Functionally yes — both name the identical gzip-compressed tar structure. GNU tar's automatic format detection recognizes either extension interchangeably, though some other tools and scripts expect one specific naming convention.

Can I extract a single class file from a tar.gz without unpacking the whole thing?
Not efficiently. Gzip's RFC 1952 format has no index or central directory, so a decompressor has to process the stream from the beginning up through wherever that file's data sits in the underlying tar layout.

Does the JDK have any built-in support for tar.gz at all?
Partially. java.util.zip.GZIPOutputStream and GZIPInputStream, both part of the standard library, handle the gzip compression layer directly. What the JDK lacks is any built-in class for the tar container itself, so building the archiving layer still requires a third-party library like Apache Commons Compress.