JavaCVを使って画像処理のコードを書きました。作成したアプリをPaaSで動かしたかったので依存関係全部入りのfat JARを作ったのですが、大したアプリではないのにJARのファイルサイズがとても大きくなってしまったので、ファイルサイズの削減を試みます。
fat JARの作成方法から知りたい場合は↓の記事をご参照ください。
もともとのJARファイルサイズ
もともとのbuild.gradle
には、JavaCVのREADMEにしたがって↓のように依存関係を記述していました。
dependencies {
implementation group: 'org.bytedeco', name: 'javacv-platform', version: '1.5.6'
}
すると生成されたJARファイルのサイズは779Mとなり、とても大きいものになりました。
$ ls -lh build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
-rw-r--r-- 1 user staff 779M Nov 7 07:17 build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
こんなに大きいとPaaSへのデプロイに無駄に時間がかかってあれなので、JARファイルのサイズ削減してみました。
JARファイルのサイズ削減
今回はOpenCVをJavaで使いたくてJavaCVを利用しました。
JavaCVはOpenCV以外のライブラリも色々とラップしているので、方針としては使っていないライブラリは極力依存関係に含めないようにしたいと思います。
結論だけ先に書いておくと、おすすめは方法3です。
方法1:不要なライブラリを依存関係から除外するパターン
依存関係にjavacv-platform
を単純に指定しただけではOpenCV以外の諸々のライブラリも含まれてしまうので、↓のように使っていないライブラリを明示的に指定して、依存関係に追加しないようにしてしまいます。
dependencies {
implementation group: 'org.bytedeco', name: 'javacv-platform', version: '1.5.6', {
exclude module: 'ffmpeg-platform'
exclude module: 'flycapture-platform'
exclude module: 'libdc1394-platform'
}
}
とりあえず↑の3つだけ除外してJARファイルを作ってみると、ファイルサイズは606Mまで削減できました。
$ ls -lh build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
-rw-r--r-- 1 user staff 606M Nov 7 07:35 build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
方法2:必要なライブラリのみ依存関係に追加するパターン
頑張って使ってないもの全部除外するのは面倒なので、はじめからOpenCV部分だけ依存関係に追加すればいいんじゃない?と思ってやったのがこれになります。
dependencies {
implementation group: 'org.bytedeco', name: 'opencv-platform', version: '4.5.3-1.5.6'
}
↓のpom.xml
を見てjavacv-platformの依存関係を調べて、opencv-platformだけあれば大丈夫そうだなと思ってこの方法試してみて、実際動作的には問題ありませんでした。
結果としてはJARファイルのサイズを464Mまで削減することができました。
$ ls -lh build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
-rw-r--r-- 1 user staff 464M Nov 7 07:40 build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
方法3:必要なライブラリのみ依存関係に追加するパターン その2
方法2でOpenCV以外の依存関係は除外することに成功しました。
ただ、方法2で依存関係に追加したopencv-platform
はWindows、macOS、Linux、Android、iOSといったあらゆる環境で動作するように、各環境向けのライブラリファイルも含まれています。
今回作ったアプリは
- 開発環境はMacまたはWindows、本番環境はLinux
- 開発環境も本番環境も64ビット版OSで動作
といった前提なので、AndroidやiOS、armやx86環境向けの諸々は依存関係に含めなくても良さそうです。
なので必要な環境向けの依存関係のみ記述してやります。
dependencies {
implementation group: 'org.bytedeco', name: 'opencv', version: '4.5.3-1.5.6'
implementation group: 'org.bytedeco', name: 'opencv', version: '4.5.3-1.5.6', classifier: 'linux-x86_64'
implementation group: 'org.bytedeco', name: 'opencv', version: '4.5.3-1.5.6', classifier: 'macosx-x86_64'
implementation group: 'org.bytedeco', name: 'opencv', version: '4.5.3-1.5.6', classifier: 'windows-x86_64'
implementation group: 'org.bytedeco', name: 'openblas-platform', version: '0.3.17-1.5.6'
}
これはopencv-platform
のpom.xml
の依存関係を見て、必要な環境向けの依存関係だけ抜き出してきたものになります。
上記pom.xml
ではclassifier
の部分は変数化されていますが、大本はここに定義してあります。
この状態でJARを作ると、204Mまでサイズダウンできました。
$ ls -lh build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
-rw-r--r-- 1 user staff 204M Nov 7 08:52 build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
これでもともとのファイルサイズの1/4強までサイズを削減することに成功しました。
方法4:必要なライブラリのみ依存関係に追加するパターン 番外編
基本は方法3と同じで真新しいものはないので番外編としています。
更に依存関係を細かく整理して、さらなるサイズ削減を目指してみます。あまり細かくすると新しい環境に対応したい場合の保守コストが上がるので、個人的には方法3くらいまでで妥協できるならしておくのがいいと思います。
さて、方法3で依存関係にopenblas-platform
を含めていましたが、実はこれも各環境向けのライブラリファイルが含まれています。openblas-platform
の依存に入っているjavacpp-platform
も各環境向けのライブラリが存在します。
といったように、依存関係を下れるだけ下って必要最低限のものだけ追加するようにしてみたら、↓のような感じになりました。
dependencies {
implementation group: 'org.bytedeco', name: 'opencv', version: '4.5.3-1.5.6'
implementation group: 'org.bytedeco', name: 'opencv', version: '4.5.3-1.5.6', classifier: 'linux-x86_64'
implementation group: 'org.bytedeco', name: 'opencv', version: '4.5.3-1.5.6', classifier: 'macosx-x86_64'
implementation group: 'org.bytedeco', name: 'opencv', version: '4.5.3-1.5.6', classifier: 'windows-x86_64'
implementation group: 'org.bytedeco', name: 'openblas', version: '0.3.17-1.5.6'
implementation group: 'org.bytedeco', name: 'openblas', version: '0.3.17-1.5.6', classifier: 'linux-x86_64'
implementation group: 'org.bytedeco', name: 'openblas', version: '0.3.17-1.5.6', classifier: 'macosx-x86_64'
implementation group: 'org.bytedeco', name: 'openblas', version: '0.3.17-1.5.6', classifier: 'windows-x86_64'
implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.6'
implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.6', classifier: 'linux-x86_64'
implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.6', classifier: 'macosx-x86_64'
implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.6', classifier: 'windows-x86_64'
}
これでJARファイルを作成すると136Mまでファイルサイズが減りました。
$ ls -lh build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
-rw-r--r-- 1 user staff 136M Nov 7 09:22 build/libs/javacv_url_image_loader-1.0-SNAPSHOT-all.jar
最終的に当初のJARのファイルサイズの1/5以下までファイルサイズを削減することができました。これでJARファイルの生成とかデプロイがかなり高速化できました。
蛇足ですが、今回はmacOS、Windows、Linuxの3種類のOSで動作するようにしましたが、これをさらに例えばmacOSだけで動けばいいように依存関係を絞ると40M程度までサイズダウンできます。
参考:
コメント