
Pure-Go Java Decompiler and Serialization Operator
A portable, pure-Go Java toolkit — extracted and trimmed from yaklang — focused on four things:
.class / .jar / .war / .zip → readable Java source..dex / .apk → deterministic .jar, or directly
to readable Java source, without invoking an external dex2jar tool..class file (constant pool,
fields, methods, version, access flags).Built for portability and embedding:
javajive facade package wraps all four
capabilities; the sub-packages remain available for advanced use.decompile, dex2jar, classinfo, and serial
subcommands, built on the standard library..class / .jar and
JDK-serialized blobs with javac/java, then verifies JavaJive against them
(see HARNESS-WORKFLOW.md).utils / codec / log / go-funk are
reimplemented as a minimal, self-contained internal/ core.The complete 38-JAR differential audit reports zero recorded regressions against the fixed baseline: all 20 previously compile-clean JARs are retained and 26 now compile in full. Baseline defects and 4 existing method stubs remain visible. See the per-JAR results and reproduction.
250 isolated semantic round trips record compilation, JVM verification, stubs and runtime equality separately; original application classes are absent from rebuilt classpaths. CI runs the semantic audit on JDK 17 and 21, the full historical comparison, and the OS/Go and race matrices. These checks do not prove equivalence of every library method. See the implementation and remaining boundaries.
The following figures were reported for v0.3.0 on 2026-09-05. They are not current-version acceptance results or proof of behavioral equivalence.
Measured on 34 real-world jars (18,759 flattened units) via decompile → javac --release 8
recompile → repackage → JVM verify:
Outer$Inner.java)
recompile with zero javac errors, and 0 syntax errors across all 34 jars (a CI-enforced
hard assertion, so no type error can hide behind a lexer failure).-Xverify:all per-class verification passes end-to-end (codec is byte-identical to the
original jar under a call differential). Locked in provenClean.See BENCHMARK.md for the full methodology, per-jar tables and reproduction commands.
A separate, CI-gated corpus exercises modern language targets rather than the
historical Java 8 libraries: Java 21 records/sealed types/pattern switches/switch
expressions, control-flow torture, Java 8 enum bodies, a 100-class scale JAR,
multi-release and modular JARs, and the packaged irreducible fixtures. Each case
is decompiled, tree-recompiled, verified with java -Xverify:all, and compared
against original runtime output. See
test/complexjar/REPORT.md for the inventory, fixed
defects and remaining boundaries.
# CLI
go install github.com/yaklang/javajive/cmd/javajive@latest
# Library
go get github.com/yaklang/javajive@latest
Or build from source:
git clone https://github.com/yaklang/javajive
cd javajive
go build -o javajive ./cmd/javajive
Requires Go 1.22+.
javajive <command> [arguments]
Commands:
decompile decompile Java artifacts or the supported DEX subset into Java source
dex2jar convert the supported DEX subset in a DEX/APK to a deterministic JAR
inspect read-only inventory and best-effort analysis of DEX/APK/JAR/WAR input
classinfo print the structure of a .class file (version, fields, methods)
serial Java serialization tools (subcommands: tojson, fromjson)
version print the version
help show help
javajive inspect app.apk --format json
javajive inspect app.war --format json
# Large applications: omit per-instruction disassembly and raw code units.
javajive inspect --disassembly=false --format json app.apk
inspect never translates input or writes a JAR. It reports the artifact hash
and format, a sorted archive inventory, canonical multidex provenance, per-class
and per-method inventory, deterministic DEX disassembly, a per-class strict
translation verdict, and precise diagnostics for the first unsupported feature
of each method. This keeps real applications analyzable even when the strict
translator cannot yet convert them.
# Single class: prints to stdout by default, or -o to write a file.
javajive decompile Foo.class
javajive decompile Foo.class -o Foo.java
# Archive: defaults to a "<input>.src" directory, or -o to choose one.
javajive decompile app.jar
javajive decompile app.war -o ./app-src
# Structured archive export: sources/, resources/, and preserved nested
# archives/ (WEB-INF/lib and EAR/lib jars are decompiled in place).
javajive decompile app.war --structured -o ./app-src
# DEX or APK: run the native DEX-to-JAR pipeline and decompile the result.
# The default output directory is "<input>.src".
javajive decompile classes.dex
javajive decompile app.apk -o ./app-src
# Directory: recursively decompile .class files (requires -o output dir).
javajive decompile ./classes -o ./src
# Very large generated methods: opt into a higher per-method analysis budget.
# Values above 1,000,000 also scale graph/scan caps.
javajive decompile Big.class -analysis-budget 2000000
javajive decompile app.jar -o ./app-src -analysis-budget 2000000
javajive dex2jar -o classes.jar classes.dex
javajive dex2jar -o app.jar app.apk