Apache POI の久々のメジャーバージョンアップである 5.0.0
が 2021-01-20
に出ました。
テストも通るしいっかーと、雑に更新したらexecutable jarのサイズが26MB増えてウケました。(笑いごとじゃない
多少のJarサイズはそれほど問題にならないことが多いのですが、今回はもともと40MB程度のJarで、それでも「ちょっと大きいなー」って思っていたのがいきなり60MBを超えただけに、ちょっと待ってくれって気分です。
そんなわけでちょっとみてみようかーと。見ていった手順をだらだら書きます。参考になるかどうかは知りません。
ちなみにPOIのソース管理は Subversion で、GitHubにあるのはミラーです。
今回ソースは読んでないけど。ライブラリのソースは本体のリポジトリじゃなく、Mavenリポジトリの -sources.jar
で読むことの方が多いと思います。でも本体の場所を知ってると、ごく稀にコミットログとか追いたくなったときに便利です。
空のjarを作るプロジェクトを作る
調べるのに他のライブラリが混ざってるとかったるいので、ピュアなプロジェクトを作ります。
ビルドにいちいち時間かかるのも嫌だし。
雑にcat
で build.gradle
を書きます。
% cat>build.gradle
plugins { id 'java' }
^C
一つもクラスを作らずにビルドします。
% gradle build
BUILD SUCCESSFUL in 537ms
1 actionable task: 1 up-to-date
できました。
中身は もはや人間が実行することもなくなった jar
コマンドでみれます。
% ls -l build/libs
total 8
-rw-r--r-- 1 irof staff 261 2 3 22:43 poi5.jar
% jar -tf build/libs/poi5.jar
META-INF/
META-INF/MANIFEST.MF
MANIFEST.MF
だけですね。この手順は「Gradleが動いてる」とかその辺の確認です。すぐ確認できるんだからすぐ確認する。あ、ディレクトリ名を poi5
にしたんでその名前になってますね。
jar
コマンドがよくわからないなら拡張子を .zip
に変えて適当に開いてやればよいです。昔はよくやってました。jarってzipなんで。
poiを入れる
引き続きcat
で追記します。
% cat>>build.gradle
repositories.jcenter()
dependencies.implementation 'org.apache.poi:poi:5.0.0', 'org.apache.poi:poi-ooxml:5.0.0'
^C
repositories
はmavenCentral
でもいいです。Gradleの次のアップデート以降で非推奨になったりするんだろな。
追記: てか jcenter
なくなります。タイムリーすぎてウケた(笑い事じゃない
implementation
とかは実務では1artifactずつ並べるんですが、今回は cat
で書いてるから滅多に使わない複数列挙をします。
repositories
とかdependencies
とかは普通 {}
で書きますが、一つだったらそのまま .
で繋げられます。滅多に役に立たない知識。
この書き方は実務ではお勧めしません。
ooxmlとかは ブログの過去ログを検索すれば……10年以上前か。当時使ってたのが3.5なので、長いこと中身読んでないなぁ。。
build.gradle全体
plugins { id 'java' }
repositories.jcenter()
dependencies.implementation 'org.apache.poi:poi:5.0.0', 'org.apache.poi:poi-ooxml:5.0.0'
しんぷる。
依存ツリーを確認
gradle dependencies
でみれます。ようするにMavenの dependency:tree
……なんだけど、IDE上でGUIで見ることの方が多いかなと思います。コマンド知らなくても特に問題ないんじゃないかな。
--configuration
無しだと compileClasspath
とか testRuntimeClasspath
とか色々でてノイズなので、眺めるときはだいたい runtimeClasspath
を使ってます。
% gradle dependencies --configuration runtimeClasspath
> Task :dependencies
------------------------------------------------------------
Root project 'poi5'
------------------------------------------------------------
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.poi:poi:5.0.0
| +--- org.slf4j:slf4j-api:1.7.30
| +--- org.slf4j:jcl-over-slf4j:1.7.30
| +--- commons-codec:commons-codec:1.15
| +--- org.apache.commons:commons-collections4:4.4
| +--- org.apache.commons:commons-math3:3.6.1
| \--- com.zaxxer:SparseBitSet:1.2
\--- org.apache.poi:poi-ooxml:5.0.0
+--- org.apache.poi:poi:5.0.0 (*)
+--- org.apache.poi:poi-ooxml-lite:5.0.0
| \--- org.apache.xmlbeans:xmlbeans:4.0.0
+--- org.apache.commons:commons-compress:1.20
+--- com.github.virtuald:curvesapi:1.06
+--- org.bouncycastle:bcpkix-jdk15on:1.68
| \--- org.bouncycastle:bcprov-jdk15on:1.68
+--- org.bouncycastle:bcprov-jdk15on:1.68
+--- org.apache.santuario:xmlsec:2.2.1
... 略 ...
+--- org.apache.xmlgraphics:batik-all:1.13
... 略 ...
\--- de.rototor.pdfbox:graphics2d:0.30
\--- org.apache.pdfbox:pdfbox:2.0.22
\--- org.apache.pdfbox:fontbox:2.0.22
削ってるからあれだけど、めっちゃいっぱい出てました。poi-ooxml由来で189個。
詳細は省略しますが、org.apache.xmlgraphics:batik-all
で約13MB、 org.bouncycastle
で約7MB、 de.rototor.pdfbox:graphics2d
で約5MB。これらで約23MBになります。増加分とほぼ合いますね。
Apache Batik はSVGを扱うもの。Bouncy Castleは暗号化。最後のはApache PDFBoxのアダプタなんでPDFを扱うものです。
なるほどこれらに対応したのかーと言う感じですね。POI使う時に制約になった記憶がうっすらあります。うっすら。(でも今回はシンプルな xlsx
扱うだけなんで使わない……)
リリースノートを確認
最初にやれ←
なるほど(わからん
ちなみに poi-ooxml-lite
とかがあって、これ使うといいんじゃ?と思いましたが、こちらは元 ooxml-schemas
と書いてるようにスキーマだけ。使いたい XSSFWorkbook
とかは入っておらずでした。
ちなみに前バージョン
% gradle dependencies --configuration runtimeClasspath
> Task :dependencies
------------------------------------------------------------
Root project 'poi5'
------------------------------------------------------------
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.apache.poi:poi:4.1.2
| +--- commons-codec:commons-codec:1.13
| +--- org.apache.commons:commons-collections4:4.4
| +--- org.apache.commons:commons-math3:3.6.1
| \--- com.zaxxer:SparseBitSet:1.2
\--- org.apache.poi:poi-ooxml:4.1.2
+--- org.apache.poi:poi:4.1.2 (*)
+--- org.apache.poi:poi-ooxml-schemas:4.1.2
| \--- org.apache.xmlbeans:xmlbeans:3.1.0
+--- org.apache.commons:commons-compress:1.19
\--- com.github.virtuald:curvesapi:1.06
こっちは省略なしです。シンプルなものですね。
上でサイズの大半を占めてるって書いてたライブラリはこっちでも使ってないし exclude
しちゃっていい気がする。
ってことで外して、テスト通って、OK。と言う感じ。
注意と昔話
Mavenの compile
スコープで宣言されるものを外すのは危険です。自信とそれを裏付ける自動テストがなければやめましょう。(とか言いながら自信はなかったりする。)
ライブラリの依存ライブラリがないと、実行時にクラスねーよって落ち方します。コンパイルチェックが効かない。せっかくコンパイル言語使ってるのにこれが起こるのはダサい。
Maven以前は自身でJarを各ライブラリの配布サイトからかき集めてクラスパスに追加する作業が必要で、この時に集めるのが漏れて実行時エラーとかは結構よくある話でした。
でも現代ではこの苦労をする必要はありません。それがMavenが変えたJavaの世界です。
自動で入る依存ライブラリを外すのは、解決済みの問題のトリガーを自身で引く行為です。
必要な場合に、ある程度(完全ではない)安全に行うには自動テストが必須です。完全じゃないってのは肝に銘じた上で。