Java Decompiler project の JD-GUI で JAR ファイルからソースコードを生成する

## 概要

- Java Decompiler project の JD-GUI で JAR ファイルからソースコードを生成する
- 今回の環境: macOS Catalina + Java 11 (AdoptOpenJDK 11.0.6)

## JD-GUI とは

クラスファイルや JAR ファイルから Java のソースコードを生成する逆コンパイラ。
Java 5 以降に導入されたアノテーション、ジェネリクス、列挙型などもサポートしているとのこと。

[Java Decompiler](http://java-decompiler.github.io/)

> JD-Core is a library that reconstructs Java source code from one or more “.class” files. JD-Core may be used to recover lost source code and explore the source of Java runtime libraries. New features of Java 5, such as annotations, generics or type “enum”, are supported. JD-GUI and JD-Eclipse include JD-Core library.

## ダウンロードと実行

公式サイト [Java Decompiler](http://java-decompiler.github.io/) から jd-gui-1.6.6.jar をダウンロードする。

```
$ wget https://github.com/java-decompiler/jd-gui/releases/download/v1.6.6/jd-gui-1.6.6.jar
```

java コマンドで JD-GUI を起動する。

```
$ java -jar jd-gui-1.6.6.jar 
```

<img width="1010" alt="jd1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139365/a846bf64-4466-9656-e518-502a12610a46.png">

jar ファイルをドラッグ・アンド・ドロップすると Java のソースコードに変換してくれる。

<img width="928" alt="jd2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139365/eeef762a-c470-0259-6ee5-e4f11ad15d6d.png">

メニューから File → Save All Sources でソースコードをまとめた zip ファイルを生成できる。

生成された zip ファイルを展開してみる。

```
$ unzip helloworldmod-1.2.3.jar.src.zip 
Archive:  helloworldmod-1.2.3.jar.src.zip
   creating: META-INF/
  inflating: META-INF/MANIFEST.MF    
  inflating: META-INF/mods.toml      
   creating: com/
   creating: com/example/
  inflating: com/example/HelloWorldMod.java  
  inflating: pack.mcmeta             
```

生成されたソースコードには jar ファイルのあったパスなどがコメントで埋め込まれている。

```java
$ cat com/example/HelloWorldMod.java
/*    */ package com.example;
/*    */ 
/*    */ import net.minecraft.entity.player.PlayerEntity;
/*    */ import net.minecraft.util.math.BlockPos;
/*    */ import net.minecraft.util.text.ITextComponent;
/*    */ import net.minecraft.util.text.StringTextComponent;
/*    */ import net.minecraftforge.common.MinecraftForge;
/*    */ import net.minecraftforge.event.entity.player.PlayerEvent;
/*    */ import net.minecraftforge.eventbus.api.SubscribeEvent;
/*    */ import net.minecraftforge.fml.common.Mod;
/*    */ 
/*    */ 
/*    */ @Mod("helloworldmod")
/*    */ public class HelloWorldMod
/*    */ {
/*    */   public HelloWorldMod() {
/* 17 */     MinecraftForge.EVENT_BUS.register(this);
/*    */   }
/*    */ 
/*    */ 
/*    */ 
/*    */ 
/*    */ 
/*    */ 
/*    */   
/*    */   @SubscribeEvent
/*    */   public void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
/* 28 */     PlayerEntity player = event.getPlayer();
/* 29 */     BlockPos pos = player.func_180425_c();
/*    */ 
/*    */ 
/*    */     
/* 33 */     String message = "Hello, World!\n[name]=[" + player.func_200200_C_().func_150254_d() + "]\n[pos]=[" + pos.func_177958_n() + "," + pos.func_177956_o() + "," + pos.func_177952_p() + "]";
/* 34 */     StringTextComponent stringTextComponent = new StringTextComponent(message);
/* 35 */     player.func_145747_a((ITextComponent)stringTextComponent);
/*    */   }
/*    */ }


/* Location:              /Users/johndoe/hello/build/libs/helloworldmod-1.2.3.jar!/com/example/HelloWorldMod.class
 * Java compiler version: 8 (52.0)
 * JD-Core Version:       1.1.3
 */
```

## 参考資料

- [Java Decompiler](http://java-decompiler.github.io/)
- [Java Decompiler · GitHub](https://github.com/java-decompiler)