pure Go no cgo no JDK MIT licensed

Java tooling, in pure Go. Decompile, parse, (de)serialize.

A portable, single-binary Java toolkit extracted and trimmed from yaklang. Turn .class / .jar / .war / .zip into readable Java source, inspect class structure, and convert the Java serialization wire format to and from JSON — with no JDK, no cgo, and no ANTLR runtime.

cross-tested against a real JDK CI on linux / macOS / windows

Install

One static binary for the CLI, or a single import for the library. No toolchain beyond Go.

Install the javajive command — decompile, inspect, and (de)serialize from your shell.

go install github.com/yaklang/javajive/cmd/javajive@latest

Then try javajive decompile app.jar or javajive classinfo Foo.class.

Industrial-grade, self-proven

Honest, reproducible numbers on 8 real JARs (2,252 outer classes): JavaJive measured against itself, plus a fair head-to-head against CFR 0.152 and Vineflower 1.10.1 below.

96.6%
class-clean rate — 2,175 / 2,252 outer classes recompile with zero javac errors
0
syntax errors across all 8 JARs — a CI-enforced hard assertion, so the numbers can't be phase-masked
5 / 5
self-hosted algorithms — MD5 · SHA-256 · CRC32 · quicksort · Base64 — round-trip byte-for-byte
2
libraries with full round-trip (commons-codec, gson): recompile → repackage → JVM -Xverify:all
115 / s
classes per second, single-thread end-to-end decompile (per-class concurrency scales near-linearly)
100%
JVM opcode parse coverage

Professional self-assessment — is it GA?

JavaJive is a pure-Go Java decompiler core — zero JVM, zero external process — embeddable straight into a Go security toolchain. On 8 real JARs it recompiles 96.6% of outer classes with zero javac errors and, critically, zero syntax errors (a CI-enforced hard assertion, so no type error can hide behind a lexer failure). commons-codec and gson are GA-ready: their output recompiles, repackages and passes per-class JVM bytecode verification (-Xverify:all) end-to-end — commons-codec is byte-identical to the original jar under a call differential. fastjson2 (97.2%), guava (96.4%), jsoup (98.0%), snakeyaml (99.2%) and spring-core (95.5%) are high-accuracy and production-usable for class-level reverse engineering, vulnerability auditing and patch re-compilation. Combined with 5/5 byte-identical algorithm round-trips, this is an industrially usable build for Go × Java security cross-analysis.

Per-JAR class-clean rate — compilable outer classes / total. The primary, phase-masking-proof accuracy metric (higher is better):

JAR (classes) clean / total clean % defect classes syntax err full round-trip
commons-codec (106)72 / 72100.0%00YES
gson (195)73 / 73100.0%00YES
commons-lang3 (345)187 / 19894.4%110
jsoup (238)50 / 5198.0%10
snakeyaml (231)121 / 12299.2%10
spring-core (978)620 / 64995.5%290
fastjson2 (681)514 / 52997.2%150
guava (1,892)538 / 55896.4%200
total2,175 / 2,25296.6%7702 libs

Single-thread decompile throughput — end-to-end (unzip + decompile + dump), the production archive path. darwin/arm64, 20 logical cores, Go 1.22.12:

JAR (classes) seconds classes / s
commons-codec (106)0.78136
gson (195)0.57339
commons-lang3 (345)1.99173
jsoup (238)0.88270
snakeyaml (231)0.97237
spring-core (978)4.00244
fastjson2 (681)25.6427
guava (1,892)5.66334
total40.50115

This batch shows JavaJive's own numbers only — all reproducible via BENCHMARK.md. We report class-clean rate + full round-trip + a syntax = 0 hard assertion instead of raw error-line counts, because a single syntax error phase-masks every downstream type error in a whole-jar compile. The single fastjson2 throughput outlier is one oversized method-body tail class; excluding it the other 7 jars average ~268 classes/s. The head-to-head comparison against CFR 0.152 and Vineflower 1.10.1 is shown below.

Head-to-head vs CFR & Vineflower

Same machine, same 8 JARs, same javac --release 8. The primary metric is defective outer classes / total (lower is better), collapsed to outer classes so it is comparable across tools. JavaJive is syntax-clean so its whole-tree compile is never phase-masked; CFR & Vineflower are compiled per outer class in isolation so their own syntax errors can't mask their defects — a fair, un-masked comparison.

−80%
fewer defective classes than CFR (77 vs 456) — JavaJive wins all 8 JARs
96.6%
clean-class rate — #1, ahead of Vineflower (90.8%) and CFR (79.8%)
1 of 3
the only pure-Go decompiler in the top tier — CFR and Vineflower are JVM apps

Defective outer classes / total (clean-class rate). Bold = best for that JAR. Lower defect count is better:

JAR (classes) JavaJive CFR 0.152 Vineflower 1.10.1
commons-codec (106)0/72 (100.0%)10/72 (86.1%)2/72 (97.2%)
gson (195)0/73 (100.0%)24/73 (67.1%)16/74 (78.4%)
commons-lang3 (345)11/198 (94.4%)46/198 (76.8%)6/198 (97.0%)
jsoup (238)1/51 (98.0%)5/51 (90.2%)2/51 (96.1%)
snakeyaml (231)1/122 (99.2%)10/123 (91.9%)2/121 (98.3%)
spring-core (978)29/649 (95.5%)117/649 (82.0%)74/649 (88.6%)
fastjson2 (681)15/529 (97.2%)90/530 (83.0%)40/529 (92.4%)
guava (1,892)20/558 (96.4%)154/558 (72.4%)66/558 (88.2%)
total77/2,252 (96.6%)456/2,254 (79.8%)208/2,252 (90.8%)

JavaJive beats CFR on every JAR and cuts total defective classes by 83% (77 vs 456); it ranks #1 overall, ahead of Vineflower (78 vs 208, 62% fewer), leading on serialization/JSON/codec, large generic libraries and spring-core (gson 0 vs 16, fastjson2 15 vs 40, guava 20 vs 66, commons-codec 0 vs 2, spring-core 29 vs 74) while Vineflower is steadier on commons-lang3 (6 vs 11). Measured 2026-07-02 on darwin/arm64, JDK 21 (--release 8), CFR 0.152 & Vineflower 1.10.1. Full methodology & reproduction: BENCHMARK.md §7.

Features

Three Java building blocks, one portable module — plus the supporting cast trimmed down to a self-contained core.

Decompiler

Turn .class / .jar / .war / .zip into readable Java source, with whole-archive output that mirrors the original package layout.

Class parser

Inspect the full structure of a .class file — constant pool, fields, methods, version, and access flags.

Serialization

Parse and re-marshal the Java ObjectStream wire format with byte fidelity, and convert it losslessly to and from JSON.

Portable & pure Go

No JDK, no cgo, no ANTLR runtime. Cross-compiles to a single static binary for linux / macOS / windows on amd64 and arm64.

First-class CLI

decompile, classinfo, and serial subcommands built on the standard library — small, dependency-light, scriptable.

Cross-tested with a real JDK

CI compiles real .class / .jar and JDK-serialized blobs with javac/java, then verifies JavaJive against them.

Library quickstart

Import the unified javajive package — one import covers decompilation, class parsing and serialization.

import "github.com/yaklang/javajive"

// Decompile a single class, or a whole archive into a directory.
src, err := javajive.Decompile(classBytes)
err = javajive.DecompileArchive("app.jar", "app-src")

// Inspect class structure.
obj, err := javajive.ParseClass(classBytes)
_ = obj.GetClassName()

// Java serialization: binary -> JSON -> binary.
objs, _ := javajive.ParseSerialized(raw)        // or ParseSerializedHex(hexStr)
jsonBytes, _ := javajive.SerializedToJSON(objs...)
restored, _ := javajive.SerializedFromJSON(jsonBytes)
out := javajive.MarshalSerialized(restored...)