倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

POM ファイルを書こう! 其ノ四 - Optional Dependency

今回は "optional" な依存性について見ていきましょう(一覧)。

どんな時に使う?


他のライブラリへの依存性には、以前書いた「依存性のスコープ」とは別に、その依存性が "optional" かどうかを設定することが出来ます。 これは、対象となっているライブラリを使う際に、そこに指定されているライブラリが必ずしも必要ないということを示しています。

もう少し具体的に言うと、[Library X] が [Library Y] に対して "optional" な依存性を持っているとすると、[Library X] を(自分の)プロジェクト内で使う際に、必ずしも [Library Y] を取得する必要がないということです。

勿論完全に不必要というわけではなく、何らかの機能を使用する際には手動でそのライブラリに依存性を含めなければいけないこともあります。

例えば、dom4j というライブラリにおいて、XPath 機能を使わない場合には dom4j の JAR ファイルのみをクラスパスに入れればいいだけですが、XPath 機能を使いたい場合は、別途 Jaxen というライブラリを依存性に含めなければなりません(具体的には下図や以前の記事を参照)。

一応、Maven サイトにある "optional" 依存性の説明を載っけておきます:

Marks optional a dependency when this project itself is a dependency. Confused? For example, imagine a project A that depends upon project B to compile a portion of code that may not be used at runtime, then we may have no need for project B for all project. So if project X adds project A as its own dependency, then Maven will not need to install project B at all. Symbolically, if => represents a required dependency, and --> represents optional, although A=>B may be the case when building A X=>A-->B would be the case when building X .

In the shortest terms, optional lets other projects know that, when you use this project, you do not require this dependency in order to work correctly.

どう使う?


"optional" 依存性の設定は、<dependency> 要素下に <optional> 要素を付け加えて行います:

<?xml version="1.0"?>
<project>
  ...
  <dependencies>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
      <!-- <optional> 要素の子テキストで設定 -->
      <optional>true</optional>
    </dependency>
  </dependencies>
</project>

どう処理される?


まず、依存関係が以下のようになっているとします(下図も参照):

  • 開発を行っているプロジェクトを [MyProject] とする
  • [MyProject] は [Library A] に "optional" な依存関係を持っている
  • [MyProject] は [Library B] に "compile" な依存関係を持っている
  • [Library B] は [Library C] に "optional" な依存関係を持っている

このとき、[MyProject] をコンパイルする際には、[Library A] と [Library B] がクラスパスに含められます*1。 もう少し正確に言うと [MyProject] から見れば、

  • [MyProject] の POM ファイルに設定されている "optional" 依存性は、"optional" でない依存性と同じように扱われる
  • [MyProject] が依存しているライブラリ(プロジェクト)の POM ファイルに設定されている "optional" 依存性は無視される

となっています。

*1:Maven のバージョンが 2.0 の場合は、バグのためうまく機能しません。 2.0.1 以降にアップグレードしましょう。