maven2導入TIPSその2〜optional依存

前回のjasperreportsみたいなpom.xmlを作ってしまうと、そのプロジェクトに依存する方が大迷惑だというのはわかったけど、ならどうすればいいんだ?という話が今回。
(SCOPEの方が基礎っぽいので、TIPSとしてはoptionalを優先)
結論を言うとoptional依存にすれば良いです。
以下の依存性定義のoptional要素がtrueな場合、optionalな依存となります。

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.0</version>
      <type>jar</type>
      <scope>test</scope>
      <optional>true</optional>
    </dependency>

動作は「このプロジェクトに依存しているプロジェクトではoptional依存は無視」です。
必要だけれども、このプロジェクトに依存するプロジェクトにとっては必要かどうかわからない依存につけます。

さらにわかりやすくjasperreportsの例で言うと、

  • jasperreportsでPDF出力する人にとっては、poiは必要無い。
  • jasperreportsでエクセル出力する人にとっては、iTextは必要無い。
  • jasperreports本体では両方必要。

という時、jasperreportsではoptional依存として定義して、使用側では自動的に解決されないので、PDF出力を使用する場合は、jasperreportsに加えてiTextの依存を定義すれば良いワケです。
せっかくmaven2を利用しているのに、わざわざ書かなければいけないところに若干、無駄感を感じますが、前回の強制排除をするよりはマシです。
PDF出力を使用するプロジェクトは実際にiTextに依存しているワケですし。
強制排除の方のデメリットは以下が考えられます。

  • まったく関係無いpoiについて書く必要がある
  • 経験からの推測ですが、使用する分だけ依存性を定義する方が使用しない依存を強制排除するより、記述量は少ない
  • 競合ライブラリが混在してのエラーより、ClassNotFoundの方が対処しやすい。

ということで、ライブラリとして作成するプロジェクトでは、依存性を必須であるかよく考えて、必須で無いものは全てoptionalにしてしまいましょう!
optionalを使う必要が無いような小さい粒度でのプロジェクト作成を心がける…というのがよりmaven2的な考え方のような気がしますが、プロジェクトが増えすぎるのもメンテナンス性低下しますし、どっちがいいかは正直判断つきかねてます。

前回同様Maven – POM Referenceにちゃんと書いてあるので詳しくはこちらをどうぞ。