
Décompilateur Java et opérateur de sérialisation en pur Go
.zip.class (pool de constantes,
champs, méthodes, version, drapeaux d'accès).Conçu pour la portabilité et l'intégration :
javajive englobe les trois
capacités ; les sous-packages restent disponibles pour un usage avancé.decompile, classinfo et serial,
basées sur la bibliothèque standard..class / .jar et
des blobs sérialisés par le JDK avec javac/java, puis vérifie JavaJive contre eux
(voir HARNESS-WORKFLOW.md).utils / codec / log / go-funk sont
réimplémentés sous forme d'un noyau internal/ minimal et autonome.L'audit différentiel complet de 38 JAR ne rapporte aucune régression enregistrée par rapport à la base de référence figée : les 20 JAR précédemment compilables sans erreur sont conservés et 26 compilent désormais intégralement. Les défauts de la base de référence et 4 stubs de méthodes existants restent visibles. Voir les résultats par JAR et la reproduction.
250 allers-retours sémantiques isolés enregistrent séparément la compilation, la vérification JVM, les stubs et l'égalité à l'exécution ; les classes applicatives d'origine sont absentes des classpaths reconstruits. La CI exécute l'audit sémantique sur JDK 17 et 21, la comparaison historique complète, ainsi que les matrices OS/Go et race. Ces vérifications ne prouvent pas l'équivalence de chaque méthode de bibliothèque. Voir l'implémentation et les limites restantes.
Les chiffres suivants ont été rapportés pour la v0.3.0 le 2026-09-05. Ils ne constituent pas des résultats d'acceptation de la version actuelle ni une preuve d'équivalence comportementale.
Mesurés sur 34 jars réels (18 759 unités aplaties) via décompilation → recompilation javac --release 8
→ rempaquetage → vérification JVM :
Outer$Inner.java)
recompilent avec zéro erreur javac, et 0 erreur de syntaxe sur les 34 jars (une assertion
stricte imposée par la CI, afin qu'aucune erreur de type ne puisse se cacher derrière un échec du lexer).-Xverify:all par classe réussit de bout en bout (le codec est identique octet par octet au
jar d'origine selon un différentiel d'appels). Verrouillé dans provenClean.Voir BENCHMARK.md pour la méthodologie complète, les tableaux par jar et les commandes de reproduction.
# CLI
go install github.com/yaklang/javajive/cmd/javajive@latest
# Library
go get github.com/yaklang/javajive@latest
Ou compiler depuis les sources :
git clone https://github.com/yaklang/javajive
cd javajive
go build -o javajive ./cmd/javajive
Nécessite 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
Utilisez le package façade unifié — un seul import couvre les trois capacités :
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...)
| Fonction | Objectif |
|---|---|
Decompile(classBytes) (string, error) | Décompiler les octets d'un .class |
DecompileFile(path) (string, error) | Décompiler un .class depuis le disque |
DecompileWithResolver(classBytes, resolve) | Décompiler avec un résolveur d'octets de classe |
DecompileArchive(src, dst) error | Décompiler un .jar/.war/.zip dans un répertoire |
ParseClass(classBytes) (*ClassObject, error) | Analyser les octets d'un .class |
ParseClassFile(path) (*ClassObject, error) | Analyser un .class depuis le disque |
ParseSerialized(raw) ([]JavaSerializable, error) | Analyser un flux de sérialisation |
ParseSerializedHex(hexStr) ([]JavaSerializable, error) | Analyser un flux encodé en hexadécimal |
MarshalSerialized(objs...) []byte | Ré-encoder les objets au format de transmission |
MarshalSerializedHex(objs...) string | Ré-encoder en hexadécimal |
SerializedToJSON(objs...) ([]byte, error) | Convertir les objets en JSON |
SerializedFromJSON(raw) ([]JavaSerializable, error) | Reconstruire les objets depuis JSON |
Les sous-packages sont également exportés pour un usage avancé :
classparser, classparser/jarwar, serialization.
Pour rester portable et compact, JavaJive fait quelques compromis délibérés par rapport à yaklang. Voir MIGRATE.md pour la correspondance complète et le guide de migration.
| Domaine | yaklang (amont) | JavaJive |
|---|---|---|
| Filet de sécurité ANTLR du décompilateur | re-valide le code source généré via une grammaire Java ANTLR ; dégrade les membres en stubs en cas d'échec | supprimé (dépendance lourde) ; la validation est un no-op, la sortie est émise directement |
Couche de support (utils / codec / log / go-funk) | packages partagés du monorepo | réimplémentations minimales et autonomes sous internal/ |
Générateur de gadgets yso | inclus | non inclus |
Récupération du charset des littéraux de chaîne (MatchMIMEType) | récupération optionnelle GBK/GB18030 | stubé (no-op) ; comportement inchangé dans la grande majorité des cas |
Les dépendances tierces sont limitées à un petit ensemble de bibliothèques pure-Go
(gobwas/glob, go-viper/mapstructure, samber/lo, tidwall/gjson,
segmentio/ksuid, yeka/zip, et quelques 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)
Les tests croisés JDK compilent de vrais artefacts Java au moment du test et les vérifient
contre JavaJive ; ils font un t.Skip automatiquement lorsqu'aucun JDK n'est présent. Voir
HARNESS-WORKFLOW.md pour le fonctionnement du harnais et de la 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