Releases: Kukis13/parallel-zip-gradle-plugin
Release list
v1.4.1 — ParallelZip is now @CacheableTask
Highlights
ParallelZipis now@CacheableTask. Gradle's ownZip/AbstractArchiveTaskare@DisableCachingByDefaultupstream —Zip's own stated reason is "Not worth caching," a judgment call from when archive packaging was assumed cheap.ParallelZippreviously inherited that same default rather than choosing it deliberately.- With
org.gradle.caching=true(or--build-cache), an unchanged rebuild now restores the archive straight from the build cache, skipping both the copy-walk and compression entirely — the single biggest available speedup for repeat builds, bigger than anything the compression pipeline itself can offer. - This is safe specifically because the task already produces byte-for-byte reproducible output for identical inputs, and already separates
@Inputproperties (store,level,skipAlreadyCompressed— affect the archive bytes) from@Internalones (threads— doesn't). - Verified with a real functional test: runs the task, wipes all local build state (not just the output file), reruns, and asserts the second run's outcome is genuinely
FROM_CACHEwith a still-valid archive — not just an annotation check.
Published to the Gradle Plugin Portal.
v1.4.0 — skip re-deflating already-compressed content, mmap fixes, OOM guard
Highlights
- Magic-byte already-compressed detection — entries are recognized by file signature (jars/zips, gzip, bzip2, xz, 7-zip, zstd, rar, lz4, png, jpeg, gif, webp, mp4/mov, webm/mkv, ogg, woff/woff2) and STORED immediately instead of attempting DEFLATE. Geometric-mean speedup across nine real production Zip tasks jumps from ~5.4× (1.3.0) to ~26.5×.
- New
skipAlreadyCompressedtask property (defaulttrue) — the speed above trades real archive size for it (6–17% larger across the in-build benchmark suite). SetskipAlreadyCompressed = falseto always attempt DEFLATE instead, for 1.3.x-like size when that trade isn't worth it for a given archive. - Fixed a Windows-only mmap file-lock bug — an unreleased
MappedByteBufferon a large entry's source file kept it locked against deletion/rewrite until GC, which could break a later task reusing the same file in the same Gradle daemon. - OOM guard for small Gradle daemon heaps — the mmap-path buffer budget now scales down with heap size instead of a fixed 128 MiB ceiling, and a one-time warning fires when the daemon's max heap is under 2048 MiB.
Benchmarks
Full refresh across all 9 in-build projects and all 11 fixed-corpus projects — see docs/BENCHMARKS.md.
Published to the Gradle Plugin Portal.
v1.3.0 — native libdeflate on all six platforms, fused CRC32, verified benchmarks
Highlights
- Native libdeflate accelerator on all six bundled platforms — linux/windows/macOS × x64/arm64. A single published jar carries every platform's native; unsupported platforms fall back to the pure-Java Deflater automatically.
- Fused CRC32 into compression and mmap for large entries in the native path, cutting a redundant pass over entry data.
- Verified in-build benchmark framework — swaps each sample project's real Zip task for ParallelZip and takes isolated, repeated measurements.
CI / build
- Fixed the macos-x64 leg after the macos-13 runner retirement (Dec 2025).
- windows-arm64 leg now uses Microsoft's OpenJDK 17 (Temurin ships no arm64 JDK 17).
- Fixed the native build on non-MSVC (MinGW) Windows toolchains.
Published to the Gradle Plugin Portal.
v1.2.0 — native acceleration on every major architecture
Native acceleration now covers every major platform/arch
Previously the native libdeflate accelerator only ran on linux-x64 and windows-x64 —
everywhere else (Apple Silicon, ARM Windows, Linux ARM, Intel Macs) silently fell back to
the pure-Java Deflater. This release adds native builds for the four remaining
architectures, so all six are now covered:
linux-x64,linux-arm64windows-x64,windows-arm64macos-arm64,macos-x64
CI now builds, tests, and bundles a native library per architecture, and asserts each one
is present and actually exercised before the release jar is assembled — a regression on
any single platform fails the build instead of silently falling back.
Compatibility
- No breaking changes — plugin ID, Maven coordinates, and usage are unchanged from 1.1.0.
- Any other platform/arch (e.g.
linux-riscv64) continues to fall back to the pure-Java
path automatically, exactly as before.
See the README for the
full supported-platform list.
v1.1.0 — faster codec path, new plugin coordinates
Breaking: plugin coordinates moved
The Maven group and the Gradle plugin ID moved from io.github.kukis13 to
com.ljarocki:
plugins {
id 'com.ljarocki.parallel-zip' version '1.1.0' // was io.github.kukis13.parallel-zip
}
tasks.register('dist', com.ljarocki.parallelzip.ParallelZip) { // was io.github.kukis13.parallelzip.ParallelZip
from 'build/staging'
archiveFileName = 'dist.zip'
store = false // true = STORE everything (fastest, ~larger)
threads = 12 // default: available processors
}Existing users need to update the id and any direct ParallelZip/ParallelZipPlugin
class references. Nothing else about usage changes.
What's faster
- New incompressibility sniff: probes large entries before compressing and STOREs
them instead if they clearly won't shrink (already-compressed jars/binaries/media) —
the single biggest win in this release, especially on jar-heavy archives. - Per-thread native libdeflate handle reuse + batched JNI calls, replacing
alloc-per-call, cutting overhead on archives with many small entries. - Small entries batched into fewer compression tasks, and unfiltered entries read
lazily on a worker thread instead of eagerly on Gradle's single-threaded copy walk
(the bigger of the two).
Net effect across the 11 projects in BENCHMARKS.md: parallel-zip
DEFLATE (libdeflate) is now 1.65×–9.67× faster than Gradle's Zip task (up from
1.64×–4.78× before this release), with no regressions on any corpus. DEFLATE now trades
up to ~0.8% archive size for that speed on a few corpora — still the safe default.
Compatibility
- Verified Gradle 9 support (fixed Gradle 9 deprecations) alongside Gradle 8.
- Declared Configuration Cache compatibility.
- Dropped the foojay-resolver plugin: the build now fails loudly if JDK 17 isn't
already installed, instead of silently auto-downloading one. - Fixed the native accelerator build on non-MSVC (MinGW) Windows toolchains.
Benchmarks
Full refreshed 11-project table and methodology in
BENCHMARKS.md.
v1.0.0 — first release
A multithreaded, reproducible, drop-in replacement for Gradle's Zip task.
What it does
- Drop-in for
Zip— extendsAbstractArchiveTask, so the fullCopySpecDSL
(from/into/include/exclude/rename/filter/duplicatesStrategy) works
unchanged. Swappingtype: Zipfortype: ParallelZipis a one-word change. - Parallel compression across all cores, or
STORE(skip DEFLATE entirely) for
archives that are already jar/binary-heavy. - Byte-for-byte reproducible archives — fixed write order means output is stable
across thread counts and runs, sidestepping the reproducibility blocker that kept
gradle/gradle#2774 from shipping. - ZIP64 support for archives beyond 4 GiB or 65,535 entries.
- Streaming for arbitrarily large individual entries (tested past 2 GiB), with
memory bounded to a fraction of the heap. - Native libdeflate acceleration on
linux-x64/windows-x64— measured 2.0–3.7×
faster than the JDK'sDeflateron real archives, with a safe pure-Java fallback on
every other platform/arch or if the native build ever fails to load. - Zero runtime dependencies.
Proof, not just claims
Benchmarked against the official binary distributions of 11 popular open-source Java
projects (ZooKeeper, Cassandra, Kafka, Groovy, Solr, HBase, Spark, Gradle, Flink,
SonarQube, Hadoop) — full numbers and methodology in
BENCHMARKS.md.
Usage
plugins {
id 'io.github.kukis13.parallel-zip' version '1.0.0'
}
tasks.register('dist', io.github.kukis13.parallelzip.ParallelZip) {
from 'build/staging'
archiveFileName = 'dist.zip'
store = false // true = STORE everything (fastest, ~larger)
threads = 12 // default: available processors
}See the README for full docs.
Also published to the Gradle Plugin Portal (pending first-time approval).