Spring Boot の容量を減らしてみた

## 自己紹介
<img src="https://qiita-image-store.s3.amazonaws.com/0/28302/63d28421-104b-3066-2712-768e6aded5f7.jpeg" width="150px" class="pull-right"/>

- opengl-8080
- 主に Qiita で技術メモを書いたり
- 関西の SIer 勤務

---

## Spring Boot とは
- Spring ベースのアプリケーションを簡単に作れるようにした仕組み・フレームワーク
- ビルド結果が単一の jar ファイルにまとめられる

---
## 単一 jar のメリット
- AP サーバーが同梱されているので、環境ごとに AP サーバーを用意する必要がない
- `java -jar` で起動できる楽さ

![spring-boot.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/a9ceaa24-9136-040a-63ae-c7d4d90be147.jpeg)

---
## 単一 jar のデメリット
- AP サーバーも含め全ての依存ライブラリを内包するため、ファイルサイズが大きくなる

![spring-boot.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/701ff7a6-d1b3-fba5-461f-119c50f62966.jpeg)


---
## jar サイズをがんばって減らしてみた

---
## 結果
![img1.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/5d52d512-dddd-ecc9-6283-acf8648a1dec.jpeg)


---
## 結果
![img2.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/08610143-204c-2996-2474-973e69396a07.jpeg)


---
## サイズ比較
![graph_2.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/11ffed6e-3538-14f3-db03-ca505bd92110.jpeg)



---
## どうやったのか？

---
## Java で Hello World はどうやりますか？

---
## １．コードを書く

```java:Hello.java
public class Hello {
    public static void main(String... args) {
        System.out.println("Hello World");
    }
}
```

---
## ２．javac でコンパイル
```bash
$ javac Hello.java
```

---
## ３．Hello.class が生成される
![after-javac.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/c5311fd4-2624-fcba-2f23-803b4a1cb500.jpeg)

---
## ４．java で実行
```bash
$ java Hello
Hello World
```

---
## おわかりいただけただろうか？

---
<div class="text-center">
  <img src="https://qiita-image-store.s3.amazonaws.com/0/28302/40b12d21-e0d6-2647-9123-7ed6718abf2e.jpeg" />
</div>

<div class="fa-lg text-center">コンパイル前のソースコードの方が容量が小さい！</div>

---
## javacを叩けるAPIは標準である！
![java-compiler.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/d0afe723-a380-c7b6-a367-4312c3527e47.jpeg)

https://docs.oracle.com/javase/jp/8/docs/api/javax/tools/JavaCompiler.html

---

![yaruo.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/7f7c34cd-3731-60fb-1751-6910157f15d2.jpeg)

---
## 改良版 jar の仕組み
```
|-LightweightJarExecutor.class  :
|   → 自分自身の jar の中からソースを取り出してコンパイル・実行するコード
|-...
`-src/        : Spring Boot および依存するライブラリのソース一式
  |-ch/       : logback
  |-com/      : jackson とか com.sun とか
  |-javax/    : javaee の標準 API
  |-META-INF/
  |-org/      : Spring, hibernate, JBoss, Tomcat, etc... 
  `-sample/   : Spring MVC の Hello World
```

### 起動時の動作
1. 自分自身の jar の中からソースコードを抽出し、一時ディレクトリにコピーする
1. 一時ディレクトリに出力したソースを `JavaCompiler` を使ってコンパイルする
1. コンパイル結果の出力先から `URLClassLoader` を使って Spring Boot のメインクラス（`JarLauncher`）をロードする
1. `JarLauncher` の `main()` メソッドを実行する

---
## まさに Just In Time Compile！<span class="small">(違う)</span>

---
## そのままだと無駄が多く軽量化できない
![lightweight-jar.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/06a1107f-e9d7-f8b4-7696-6fd7f477365f.jpeg)

---
## 無駄１：コメント
![lightweight-jar.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/102f112f-b029-f726-963d-bdc5c8f16e07.jpeg)


---
## 無駄２：アノテーション
![lightweight-jar.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/effc60b1-deed-1eb6-5ad7-da5fafe1b964.jpeg)

---
## 無駄３：private
![lightweight-jar.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/82defb90-bcfe-6bba-3f6b-6f88091b3b0c.jpeg)

---
## 無駄４：空白＋改行
![lightweight-jar.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/ac9f2e82-ae13-59b5-12c1-d45f211fa283.jpeg)

---
## 無駄に洗練された無駄のないコード
![lightweight-jar.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/29736de4-838a-154a-8601-a46efa61e46e.jpeg)


---
## 結果 5MB の容量削減に成功！:grin::thumbsup:
![graph_2.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/11ffed6e-3538-14f3-db03-ca505bd92110.jpeg)

---
## 代償１：起動が遅い :innocent::thumbsdown:
![lightweight-jar.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/7c7ce1e8-15fa-8c64-24f6-897e7f5161d6.jpeg)


---
## 代償２：デバッグ不可能 :joy::thumbsdown:
![lightweight-jar.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/46374c2f-99c2-9473-000e-10e385cce55d.jpeg)


---
## 良い子はマネしないでください