sbtで実行可能jarを作成した時のこと。
sbt-assemblyを使用して、
sbtコンソールからのコンパイル後に「assembly」をたたいたところ、
クラスファイルやプロパティファイルなどの重複エラーが発生した。
そんで調べてみるとsbtのjar生成時に見つかった重複ファイルは
build.sbtにMergeStrategyという設定を追加してあげることで
どちらのファイルを優先的に選択するか、
または重複ファイルを両方とも削除したりすることができる。
build.sbtに以下の記述を追加する。
大抵のことは以下の式にcaseを追加したり、
「".xml"」などの部分の拡張子を変更してあげて使用すれば大丈夫かと思う。
lazy val sampleAssemblyMergeStrategy = assemblyMergeStrategy in assembly := { case PathList(ps @ _*) if ps.last endsWith ".xml" => MergeStrategy.first case PathList(ps @ _*) if ps.last endsWith ".class" => MergeStrategy.first case PathList(ps @ _*) if ps.last endsWith ".properties" => MergeStrategy.first case x => val oldStrategy = (assemblyMergeStrategy in assembly).value oldStrategy(x) }
あとは、「MergeStrategy.first」の部分の「first」は
最初に見つかったものを選択するという意味なのだが、
削除したり結合したりもできるので適宜変更する必要はあるかと思います。
以下に参考としてMergeStrategyの設定値の種類を掲載します。
設定値 | 説明 |
---|---|
MergeStrategy.deduplicate | 既定値 |
MergeStrategy.first | クラスパスの順序で最初に一致するファイルを選択します。 |
MergeStrategy.last | クラスパスの順序で最後に一致するファイルを選択します。衝突時にはMergeStrategy.singleOrErrorのエラーメッセージが表示されます。 |
MergeStrategy.concat | 単に一致するすべてのファイルを連結し、結果を含みます。 |
MergeStrategy.filterDistinctLines | 連結されるが、重複は除外されます。 |
MergeStrategy.rename | jarファイルの名前を変更します。 |
MergeStrategy.discard | 一致するファイルを破棄します。 |
導入方法などは以下のドキュメントを参照すると良いと思います。
以上