自己紹介

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

Spring Boot とは

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

単一 jar のメリット

  • AP サーバーが同梱されているので、環境ごとに AP サーバーを用意する必要がない
  • java -jar で起動できる楽さ

spring-boot.JPG


単一 jar のデメリット

  • AP サーバーも含め全ての依存ライブラリを内包するため、ファイルサイズが大きくなる

spring-boot.JPG


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


結果

img1.JPG


結果

img2.JPG


サイズ比較

graph_2.JPG


どうやったのか?


Java で Hello World はどうやりますか?


1.コードを書く

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

2.javac でコンパイル

$ javac Hello.java

3.Hello.class が生成される

after-javac.jpg


4.java で実行

$ java Hello
Hello World

おわかりいただけただろうか?


コンパイル前のソースコードの方が容量が小さい!

javacを叩けるAPIは標準である!

java-compiler.jpg

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


yaruo.jpg


改良版 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 の中からソースコードを抽出し、一時ディレクトリにコピーする
  2. 一時ディレクトリに出力したソースを JavaCompiler を使ってコンパイルする
  3. コンパイル結果の出力先から URLClassLoader を使って Spring Boot のメインクラス(JarLauncher)をロードする
  4. JarLaunchermain() メソッドを実行する

まさに Just In Time Compile!(違う)


そのままだと無駄が多く軽量化できない

lightweight-jar.jpg


無駄1:コメント

lightweight-jar.jpg


無駄2:アノテーション

lightweight-jar.jpg


無駄3:private

lightweight-jar.jpg


無駄4:空白+改行

lightweight-jar.jpg


無駄に洗練された無駄のないコード

lightweight-jar.jpg


結果 5MB の容量削減に成功!:grin::thumbsup:

graph_2.JPG


代償1:起動が遅い :innocent::thumbsdown:

lightweight-jar.jpg


代償2:デバッグ不可能 :joy::thumbsdown:

lightweight-jar.jpg


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