fat jar, zipのメリットデメリット

前提version: Scala 2.11.7, sbt 0.13

Scalaで作成したプログラムをsbtを使用してjarファイルにする方法は sbt package だが、これで作成されるjarファイルは依存ライブラリを含まない、自分で作成したソース部分のみとなる。
プログラムの配布等を考えると、fat jarか依存ライブラリを含めて一まとめにしたzipを出力したい。

fat jarは単一のファイルとして動くので解凍の必要がなく、OSによってダブルクリックで起動できる等様々な利点があるが、依存ライブラリ全てと作成プログラムをマージすることになるのでfat jarを作成する時間が長くなるという欠点がある。

対してzip化の場合は、fat jarほどユーザフレンドリーではないという欠点があるが、依存ライブラリをivyのcacheからコピーしてくるだけでなので作成時間が短い。また作成プログラムに修正を加えた場合、解凍したzipのうち作成したプログラムのjarだけを sbt package により再作成して入れ替えればいいので、修正に伴うjar作成のコストが圧倒的に低くなる。

現在作成している依存ライブラリが個のプログラムでpackageとzip、fat jarにかかる時間を比べると、それぞれ1秒、7秒、62秒となった。
これに修正時のjar化コストを考慮すると、「初回zip + 次回以降package」と「fat jarを毎回」の差はどんどん開いていく。

それぞれ利点欠点があるのでどちらの方法でもjarをsbtで簡単に作成できるようにしたい。

build.sbt

今回使用するbuild.sbtの雛形。配置場所はSampleProject直下。

build.sbt

scalaVersion := "2.11.7"

libraryDependencies ++= Seq(
        "org.apache.poi" % "poi" % "3.14"
        , "org.apache.poi" % "poi-ooxml" % "3.14"
        , "org.apache.poi" % "poi-ooxml-schemas" % "3.14"
        , "org.apache.poi" % "poi-scratchpad" % "3.14")

fat jarの作成方法

fat jarを作成するためにはsbt-assemblyというプラグインが必要になる。
プラグインを追加するために以下のファイルを.sbt/0.13/plugins/に配置する。

plugins.sbt

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.2")

fat jar作成の実行コマンドは sbt assembly となる。

zipの作成方法

zipを作成するためにはsbt-native-packagerというプラグインが必要になる。
プラグインを追加するために以下のファイルを.sbt/0.13/plugins/に配置する。

plugins.sbt

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.1.0-RC1")

プラグインを加えた後、build.sbtに enablePlugins(JavaAppPackaging) を加えてあげる必要がある。この意味は、公式サイトに書かれている通り、package方法とarchetypeを指定する仕組みを提供しているからで、今回はサーバに配置するようなものではないコマンドラインで動かすjarを作るという目的なので、"the basic Java Application Archetype"、つまりJavaAppPackagingを使うようにしている。サーバに配置する用のJavaServerAppPackaging等もあるので、目的に合わせて設定する。

Native packager provides packaging format plugins and archetype plugins to separate configuration and actual packaging. To get started we use the basic Java Application Archetype.

build.sbt

scalaVersion := "2.11.7"
enablePlugins(JavaAppPackaging)

libraryDependencies ++= Seq(
        "org.apache.poi" % "poi" % "3.14"
        , "org.apache.poi" % "poi-ooxml" % "3.14"
        , "org.apache.poi" % "poi-ooxml-schemas" % "3.14"
        , "org.apache.poi" % "poi-scratchpad" % "3.14")

zip作成の実行コマンドは sbt universal:packageBin となる。
universalの部分がWindowsでもLinuxでも使えるpackage方法として、普遍的なzipを指定していることになる。