倭マン's BLOG

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

POM ファイルを書こう! 其ノ弐 - 依存性の追加

今回は Maven2 プロジェクトに対して、他のライブラリへの依存関係を付加する仕方を見ていきます(一覧)。

以下で例として仕様するライブラリの groupId, artifactId, version を示しておきます:

groupId artifactId version 備考
commons-logging commons-logging 1.1 ロギング・コンポーネント
junit junit 3.8.1 テスティング・フレームワーク

ライブラリへの依存関係を追加する


これは前回にやりました:

<?xml version="1.0"?>
<project>
  ...
  <dependencies>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1</version>
    </dependency>
  </dependencies>
</project>

要は、groupId, artifactId, version を指定すれば良かったんでしたね。 それらの調べ方は前回参照。

scope 要素


★スコープとは?★

スコープとは、ライブラリを使用する範囲のことです。 いつそのライブラリを使うか?いつクラスパスに含めるか?ということを指定します。

スコープに指定できる値は以下の5つです:

スコープ ライブラリを使用する時 備考
compile コンパイル時と実行時 デフォルト値
provided コンパイル時 -
runtime 実行時 -
test テストのコンパイル時、実行時 -
system コンパイル時 -


何も指定しなかった場合は "compile" が指定されたと見なされます。

"compile" は常にライブラリをクラスパスに含めます。 スコープが分からないときは、とりあえずこれにしておきましょう(というか指定しなくてかまいません)。

"provided" はコンパイル時には必要だが、実行時には実行環境(runtime environment)がその実装を提供するため、開発者側が提供する必要のない依存関係に指定します。 Web アプリケーションを開発する際の Servlet API などがそれに当たります。 Servlet API の実装はサーブレットコンテナが提供するので、アプリケーション開発者が用意する必要はありません。

つーか、Servlet API 以外にいつ使うんでしょう? とりあえず、2つほど考えてみました:

  • まず、特定の実行環境がある場合ですね。 EclipseFirefox などプラガブルなアプリケーションがあって、その(Java で書かれた)要求インターフェースがパッケージングされて公開されている場合、そのプラグインを開発する際に "protected" を指定すると良いでしょう。
  • また、次の "runtime" スコープと組み合わせてインターフェースと実装を分離したりすることもやろうと思えば出来ますが・・・ ちょっとユーザにあれこれ指定してもらわないといけなくなりそうな気がします。

"runtime" は "provided" とは逆に、実行時のみに必要な依存関係に指定します。 これまた、いつ使うんでしょう? 

  • 依存関係があるライブラリで何らかのインターフェースが "provided" で指定されていて、実装をユーザ側で用意しなければならないとき。 でもこの場合、依存関係の指定をユーザに行わせるので、使う側は少々煩わしさを感じます。
  • 何らかのライブラリで拡張機能を使いたい場合。 依存関係を指定しなくても(低機能ではあるけど)キチンと動作するなっていれば、拡張機能を使いたいユーザにだけ依存関係の設定をすればよいことになります。 例えば、ロギング・コンポーネントの commons-logging などがそういう実装になってます*1

"test" はテストのコンパイル&実行の時だけ使う依存関係に指定します。 分かり易い例はテスティング・フレームワークJUnit です。

"system" は概ね "provided" と同様ですが、ここでは省略します。

★スコープの指定の仕方★

pom.xml でスコープの指定をする仕方を見てみましょう。 例えば JUnit をスコープ "test" で依存関係に追加するには <dependencey> 要素下に <scope>要素を追加します:

<?xml version="1.0"?>
<project>
  ...
  <dependencies>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1</version>
    </dependency>

    <!-- ここから -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!-- ここまでを追加 -->
  </dependencies>
</project>

次回は依存関係の推移性をやる予定です。

*1:と言いつつ、commons-logging に依存関係を指定すると、log4j がダウンロードされてしまい、半強制的にそれを使用させられますが・・・