
Reiner-Go Java-Decompiler und Serialisierungsoperator
.zip.class-Datei inspizieren (Konstantenpool,
Felder, Methoden, Version, Zugriffsflags).Gebaut für Portabilität und Einbettung:
javajive-Facade-Paket umschließt alle drei
Fähigkeiten; die Unterpakete bleiben für fortgeschrittene Nutzung verfügbar.decompile-, classinfo- und serial-Unterbefehle,
auf Basis der Standardbibliothek..class / .jar und
JDK-serialisierte Blobs mit javac/java und verifiziert JavaJive dagegen
(siehe HARNESS-WORKFLOW.md).utils / codec / log / go-funk sind
als minimaler, eigenständiger internal/-Kern neu implementiert.Der vollständige 38-JAR-Differenz-Audit verzeichnet null dokumentierte Regressionen gegen die feste Baseline: alle 20 zuvor kompilier-sauberen JARs bleiben erhalten und 26 kompilieren nun vollständig. Baseline-Defekte und 4 bestehende Methoden-Stubs bleiben sichtbar. Siehe die Ergebnisse pro JAR und Reproduktion.
250 isolierte semantische Round Trips erfassen Kompilierung, JVM-Verifikation, Stubs und Laufzeitgleichheit getrennt; ursprüngliche Anwendungsklassen fehlen in neu gebauten Classpaths. CI führt den semantischen Audit auf JDK 17 und 21, den vollständigen historischen Vergleich sowie die OS/Go- und Race-Matrizen aus. Diese Prüfungen beweisen nicht die Äquivalenz jeder Bibliotheks- methode. Siehe die Implementierung und verbleibende Grenzen.
Die folgenden Zahlen wurden für v0.3.0 am 2026-09-05 berichtet. Sie sind keine Akzeptanzergebnisse der aktuellen Version und kein Beweis für Verhaltensäquivalenz.
Gemessen an 34 realen Jars (18.759 abgeflachte Einheiten) via decompile → javac --release 8
Recompile → Repackage → JVM-Verify:
Outer$Inner.java)
kompilieren mit null javac-Fehlern neu, und 0 Syntaxfehler über alle 34 Jars (eine CI-erzwungene
harte Assertion, sodass kein Typfehler sich hinter einem Lexer-Fehler verstecken kann).-Xverify:all-Verifikation pro Klasse läuft Ende-zu-Ende durch (Codec ist byte-identisch zum
Original-Jar unter einem Call-Differential). In provenClean festgeschrieben.Siehe BENCHMARK.md für die vollständige Methodik, Tabellen pro Jar und Reproduktionsbefehle.
# CLI
go install github.com/yaklang/javajive/cmd/javajive@latest
# Library
go get github.com/yaklang/javajive@latest
Oder aus dem Quellcode bauen:
git clone https://github.com/yaklang/javajive
cd javajive
go build -o javajive ./cmd/javajive
Erfordert Go 1.22+.
javajive <command> [arguments]
Commands:
decompile decompile .class/.jar/.war/.zip or a directory into Java source
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
# 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
# Directory: recursively decompile .class files (requires -o output dir).
javajive decompile ./classes -o ./src
javajive classinfo Foo.class
class: InvisibleAnnoSeed
super: java/lang/Object
version: 61.0
access: public
constants: 18
fields (0):
methods (2):
<init>()V
run()I
# Serialized binary -> JSON. (-hex: input is a hex string, -: read from stdin)
javajive serial tojson dump.bin
printf 'aced000574000568656c6c6f' | javajive serial tojson -hex -
# JSON -> serialized binary. (default prints hex; with -o writes raw bytes)
javajive serial fromjson dump.json -o out.bin
javajive serial fromjson dump.json # prints hex
Verwende das einheitliche Facade-Paket — ein Import deckt alle drei Fähigkeiten ab:
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...)
| Funktion | Zweck |
|---|---|
Decompile(classBytes) (string, error) | Dekompiliert die Bytes einer .class |
DecompileFile(path) (string, error) | Dekompiliert eine .class von der Festplatte |
DecompileWithResolver(classBytes, resolve) | Dekompiliert mit einem Class-Bytes-Resolver |
DecompileArchive(src, dst) error | Dekompiliert ein .jar/.war/.zip in ein Verzeichnis |
ParseClass(classBytes) (*ClassObject, error) | Parst die Bytes einer .class |
ParseClassFile(path) (*ClassObject, error) | Parst eine .class von der Festplatte |
ParseSerialized(raw) ([]JavaSerializable, error) | Parst einen Serialisierungsstream |
ParseSerializedHex(hexStr) ([]JavaSerializable, error) | Parst einen hex-kodierten Stream |
MarshalSerialized(objs...) []byte | Kodiert Objekte neu ins Wire-Format |
MarshalSerializedHex(objs...) string | Kodiert neu nach Hex |
SerializedToJSON(objs...) ([]byte, error) | Konvertiert Objekte nach JSON |
SerializedFromJSON(raw) ([]JavaSerializable, error) | Baut Objekte aus JSON neu auf |
Die Unterpakete sind ebenfalls für fortgeschrittene Nutzung exportiert:
classparser, classparser/jarwar, serialization.
Um portabel und klein zu bleiben, trifft JavaJive einige bewusste Kompromisse gegenüber yaklang. Siehe MIGRATE.md für die vollständige Zuordnung und den Migrationsleitfaden.
| Bereich | yaklang (Upstream) | JavaJive |
|---|---|---|
| Decompiler-ANTLR-Sicherheitsnetz | re-validiert den gedumpten Quellcode über eine ANTLR-Java-Grammatik; degradiert Member zu Stubs bei Fehlschlag | entfernt (schwere Abhängigkeit); Validierung ist ein No-op, Ausgabe wird direkt emittiert |
Support-Schicht (utils / codec / log / go-funk) | geteilte Monorepo-Pakete | minimale eigenständige Neu-Implementierungen unter internal/ |
yso-Gadget-Generator | enthalten | nicht enthalten |
String-Literal-Charset-Wiederherstellung (MatchMIMEType) | optionale GBK/GB18030-Wiederherstellung | gestubbt (No-op); Verhalten unverändert für die überwiegende Mehrheit der Fälle |
Drittanbieter-Abhängigkeiten sind auf eine kleine Menge reiner Go-Bibliotheken beschränkt
(gobwas/glob, go-viper/mapstructure, samber/lo, tidwall/gjson,
segmentio/ksuid, yeka/zip und einige golang.org/x/*).
go test ./... # unit tests + JDK cross-tests (skipped if no JDK)
go test ./... -race # data-race free (linux)
go test ./test/cross/ -v # Java cross-tests only (needs javac/java on PATH)
Die JDK-Kreuztests kompilieren echte Java-Artefakte zur Testzeit und verifizieren sie
gegen JavaJive; sie t.Skipen automatisch, wenn kein JDK vorhanden ist. Siehe
HARNESS-WORKFLOW.md für die Funktionsweise von Harness und CI.
javajive.go unified facade package (import "github.com/yaklang/javajive")
serialization/ Java serialization/deserialization (from yaklang common/yserx)
classparser/ class parser + decompiler (from yaklang common/javaclassparser)
cmd/javajive/ CLI entry point
internal/ trimmed self-contained support layer (log / codec / funk / utils / filesys / ...)
test/cross/ JDK-backed cross-tests (javac/java)
site/ static landing page deployed to GitHub Pages