japan.internet.com
japan.internet.com メンバーID
Twitter
Facebook
RSS
ピックアップ
2007年1月9日 10:00
DevX
DevX japan.internet.com 編集部(japan.internet.com)メールホームrss
米国 WebMediaBrands が運営する、
企業向けアプリケーションの開発者向けの技術情報/サービスサイト。

Apache MavenによるJavaプロジェクトポータビリティの向上

著者Eric Redmondオリジナル版を読む海外海外発

はじめに

 皆さんのソフトウェア開発のライフサイクルが私のものと似ているとすれば、ライフサイクルはそれぞれ独自のプロジェクト構成を必要とする複数のフェーズに分かれていて、そのためにこれらの異なるフェーズを経てプロジェクトを進行させることが難しくなっているかもしれません。例えば、開発フェーズではローカルのデータベースに接続することを要求しているのに、統合テスト環境のデータベースはローカルではない場合があります。そして、テストデータベースは必ずと言っていいほど本番データベースと異なります(そうであることを願います)。

 そこで役立つのが、Apache Maven 2です。Apache Maven 2では、1つのポータブルなプロジェクトオブジェクトモデル(Project Object Model:POM)を作成できるので、統合テスト担当者や開発チームはプロジェクトに変更を加える作業から解放されます。Mavenは、プロジェクト構造の適用、プロジェクトの依存性管理、プロジェクトのカプセル化、組み込みサイトの生成、さらにSubversionやContinuumなどのツールとのシンプルな統合を実現することに加え、柔軟性を維持しながらポータビリティをできるだけ単純にすることを目指しています。そのために、Mavenにはビルドのポータビリティ問題に対応するための2つの主要ツールとして、プロパティとプロファイルが用意されています(Javaビルドのポータビリティの歴史については、「補足説明1 MakeからMavenへ」を参照してください)。

補足説明1 MakeからMavenへ
 プロジェクトのポータビリティを一番適切に表現しているのは、「プロジェクトをどれくらい簡単に別のマシンに移してビルドすることができるか」という質問と、この質問に対する答えです。つまり、正しい成果物を生成するビルド環境を構築するのにどのくらいの(そしてどのような種類の)修正を加えなければならないかということです。仮想マシン以前は、コードを実行する各タイプのマシンでコードをコンパイルしなければなりませんでした。
 Javaにはこの問題はありませんが、他の問題があります。心配しなければならないのは、コンパイルのポータビリティ問題(バイト順序や命令セットの違いなど)ではなく、ビルドプロセスそのもののポータビリティ問題だけです。
 従来のビルドツールは増分変更によってこの問題に取り組みました。Makeは、シェルスクリプトとは対照的に、その一貫性のあるほぼ抽象的な構文により、従来のメソッドよりもポータビリティに優れていました。ただし、マシン固有のマシンツールに依存しているため、最新の標準ではほとんどポータビリティはありません。Antは、Makeのマシンポータビリティ問題を解決するために作成されたものですが、独自の問題を抱えています。Antのタスクにはマシン間のポータビリティはありましたが、タスクのユーザーは必要なタスクが含まれているjarを手動でダウンロードしてインストールしなければなりませんでした。
 Mavenは、Antのマシンポータビリティ性を拡張して、オンラインリポジトリを通じたネットワークポータビリティを追加しました。ビルドに特定のゴールがなくても問題ありません。Mavenが自動的にダウンロードしてインストールしてくれます。必要なのは、プロジェクトを定義するためのプロジェクトオブジェクトモデル(Project Object Model:POM)だけです。とは言え、問題はまだ残っています。Mavenではビルドツールのポータビリティは大幅に改善されましたが、プロジェクトそのもののポータビリティはまだ解決されていません。
 現在では、ポータビリティ問題の大部分はプロジェクト設計の領域で取り扱われています。この傾向をよく表しているのが、さまざまなコンポーネントを外部化するという試みです。例えば、特定のURL(JDBCおよびHTTP)の外部化、ストリングの共通化(少なくとも.propertiesファイル内のストリング)、ネーミングサービス(JNDIなど)の使用などがあります。さらに、依存性を外部で定義してIoCコンテナ(SpringやPlexusなど)を介して注入するという手法もあります。しかし、こうしたやり方は、他のファイルに負担を転嫁しているだけではないでしょうか。もちろんそうですが、これらのファイルを利用することでコードの処理/生成を回避できるようになり、ポータビリティ問題は大幅に単純化されています。

プロパティとプロファイル

 MavenのプロパティはAntのプロパティとまったく同じです。値のプレースホルダであり、事前設定済みのものもあります。4つの異なるスタイルのプロパティを利用することができます。

  1. env.X
  2. 変数にプレフィクス「env」を付けると、シェルの環境変数が返されます。例えば、${env.PATH}を指定すると$path(Windowsでは%PATH%)環境変数が返されます。
  3. project.x
  4. POMでドット(.)付きのパスを指定すると対応する要素の値が返されます。例えば、<project><version>1.0</version></project>にアクセスするには、${project.version}を指定します。
  5. システムプロパティ
  6. ${java.home}など、java.lang.System.getProperties()を介してアクセスできるプロパティはすべて、POMプロパティとして利用することができます(POMをデバッグする近道については、「補足説明2 プロパティ値を表示する」を参照してください)。
  7. x
  8. <properties />要素または外部ファイル内に設定されている値は、${someVar}として使用することができます。

 Mavenでは、プロパティと共に、ビルドプロファイルの概念も追加されました。これは、環境要因に基づいてPOMに全面的な変更を加えるためのソリューションです。Antベースのビルドにおける共通のプラクティスは、複数の環境にまたがってプロジェクトをビルドするための方法をプロパティとして表現することでした。Mavenでは、問題を単純化するために、このような手続き的アプローチを排除して、代わりに「あるプロファイルがアクティブの場合には、これらの設定を使う」という宣言を用います。プロファイルをアクティブにするには、次のような方法があります。

  • アクティベーション
  • 例えば、「JDK1.4でコンパイルする場合にこのプロファイルアクティブにする」などと定義します。
  • コマンドライン
  • 引数-P <profileID>を使用します。
  • アクティブプロファイル
  • 「settings.xml」ファイル内のある要素に含まれている<activeProfile>profileID</activeProfile>要素を使用します。

 プロファイルの詳細については、Mavenのサイトのガイドを参照することをお勧めします。

補足説明2 プロパティ値を表示する
 特定のパラメータの値をデバッグする必要がある場合は、次のように「pom.xml」ファイル内でAntプラグインを構成します。
<project>
  ....
  <build>

    <plugins>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <configuration>
          <tasks>

            <echo>${project.build.directory}</echo>
          </tasks>
        </configuration>
      </plugin>

    </plugins>
  </build>
  ...
</project>
 その後、次のようにしてこのプラグインを実行します。
mvn antrun:run
 Antプラグインは文字列値を返します。

ポータビリティのレベル

 これらの基本ツールを押さえておけば、自分のJavaプロジェクトのポータビリティがどの程度のレベルに位置しているかを正しく判別することができます。Mavenでは、Javaポータビリティとそれに対応する問題点を次の4つのレベルで表現します。

  • ワイド(Wide)
  • インハウス(In-house)
  • 環境的(Environmental)
  • 非ポータブル(Non-portable)

ワイド(Wide)

 Mavenの世界で「ポータビリティがワイドである」と言えば、誰でもそのプロジェクトのソースをダウンロードし、修正なしでコンパイルし、POMまたは標準Maven以外の要件にインストールできるということです。これが一番高いレベルのポータビリティです。同じプロジェクトをビルドするユーザーは、余計な作業を実行する必要がほとんどありません。このレベルのポータビリティは、特にオープンソースプロジェクトで重要視されます。オープンソースプロジェクトが成功するためには、コントリビュータになる可能性を持った人が簡単にプロジェクトをダウンロードしてインストールできるようにすることが必要だからです。

 ご想像の通り、一番高いレベルのポータビリティは、手に入れることも一番困難です。ワイドなポータビリティを実現するためには、広く配布されているプロジェクトやツールであっても、ライセンスの問題が考えられるため、それに依存するわけにはいきません(この理由で、市販のソフトウェアパッケージのほとんどは利用不可になります)。また、Mavenの成果物として配布されるソフトウェアコンポーネントについても、同様の問題が考えられます。例えば、皆さんのプロジェクトでMySQLを利用している場合、ユーザーはプロジェクト本体に加えてMySQLもダウンロードしてインストールしなければなりません。これではポータビリティがワイドであるとは言えません(システムを変更せずに使用できるのはMySQLの既存ユーザーだけです)。一方、HSQLDBを使用している場合は、MavenのセントラルリポジトリからHSQLDBを入手できるので、ポータビリティはワイドとなります。

インハウス(In-house)

 ほとんどの重要なソフトウェア開発では、インハウスのポータビリティがおそらく望むことのできる最高レベルのポータビリティです。オープンソースの開発チームにしろ、クローズドソースの製作会社にしろ、ソフトウェアプロジェクトの大多数はこのレベルに位置します。このレベルのポータビリティの中心にあるのが、選ばれたユーザーのみが内部(インハウス)のリモートリポジトリにアクセスできるというプロジェクト要件です。インハウスとは、必ずしも特定の会社を意味するのものではありません。幅広く普及しているオープンソースプロジェクトの中には、特定のツールや接続アクセスを必要とするものがあるかもしれません。このような場合はインハウスに分類されます(このレベルについての詳細は、「補足説明3 インハウスポータビリティの詳細」を参照してください)。

補足説明3 インハウスポータビリティの詳細
 インハウスポータビリティのもう1つの例として、インハウスのメンバが接続できる共通データベースがあります。インハウスのプロジェクトをインハウスのネットワークの外側(例えば、企業のファイアウォールの外側)で一からビルドしようとすると、失敗します。失敗の原因としては、必要なカスタムプラグインが利用できないことや、プロジェクトの依存性が見つからないことが考えられます。従って、このプロジェクトはインハウスでのみポータブルとなります。
 インハウスポータビリティ自体には何も問題がないので、プロジェクトの形を変えて、これを避けようとしないでください。プロジェクトを複数の相互依存関係のあるパーツに分割することに意味がある場合は、分割してかまいません。Mavenのセントラルリポジトリでは入手できないバージョンを使うことに意味がある場合は、使ってかまいません。プロジェクトのPOMのrepository要素を用いて独自のパブリックリポジトリと参照依存性を作成すれば、誰もが切望する「ワイドなポータビリティ」を実現することができます。

環境的(Environmental)

 Mavenでは、コードとリソースの生成に主に関係する、環境的なポータビリティレベルのプロファイルが作成されます。例えば、本番データベースとは別のデータベースを使うテスト環境があるとします。本番データベースとテストデータベースが異なるため、テストマシンでビルドした場合は、少なくとも1つのリソースファイルを(または最悪の場合はコードも)修正しなければなりません。ファイルを変更しなければ正しくビルドして特定の環境で実行することができない場合、そのプロジェクトはよくても環境的なポータビリティしか実現していません。例えば、テスト環境内のテストデータベースへの参照と本番環境内の本番データベースへの参照を含むプロジェクトは、環境的なポータビリティを実現しています。ただしこのプロジェクトは、未定義でプロファイルも作成されていない別の環境に移動すると動作しなくなります。従って、定義された環境間でのみポータビリティがあると言えます。

 本稿のサンプルプロジェクトは環境的なポータビリティを実現しています。

非ポータブル(Non-portable)

 非ポータブルなプロジェクトは、特定の状況および条件下(例えば、ローカルマシンなど)でしかビルドできません。プロジェクトを別のマシンに移動する計画が絶対にない場合を除き、非ポータブルにすることは避けてください。非ポータブルということは、定義が1つしかない環境的ポータビリティと同じです。つまり、プロジェクトは1つの環境設定下でしかビルドできません。

 プロジェクトがどのレベルに位置するかを判断する方法については、「補足説明4 ポータビリティレベルの判断方法」を参照してください。

補足説明4 ポータビリティレベルの判断方法
 ビルドのポータビリティは、プログラミングそのものと同様、科学であると同時に芸術でもあります。どのレベルに位置するかは主に各プロジェクトの目標によって決まり、その上、「正しい」答えはまずありません。慣習と、ユーザーの期待によって決まるのです。何が妥当であるかに基づいて最善の判断を下してください。ユーザーがすべてJDK 1.6を実行していることがわかっている場合は、ユーザーに対してワイドなポータビリティを実現していると宣言しても問題ないでしょう。しかし、JDK 1.5を実行しているユーザーの方が多い場合に、ユーザーに1.6のインストールを要求することは妥当ではないので、おそらくポータビリティをインハウスレベルまで下げることになります。これは、ユーザーにまず「JDK 1.6クラブ」のメンバになるよう頼むようなものだと考えてください。
 ターゲットユーザーだけを対象とするようにビルドを調整する必要があります。プロジェクトのポータビリティの調整に悩む前に、次の質問に答えてください。
  • ワイドなポータビリティ
  • できるだけ多くの人がプロジェクトをダウンロードしてビルドできるようにしたいですか? ユーザー間で一般的に使われている最小限の構成で済ませることはできますか?
  • インハウスのポータビリティ
  • 依存コンポーネントのライセンス問題やプロジェクト構造の都合上、プロジェクトにクローズドリポジトリを設ける必要がありますか? 他の開発者はプライベートネットワークへのアクセスを心配していますか?(ネットワークがプライベートでない場合、ポータビリティはワイドになる可能性があります)
  • 環境的なポータビリティ
  • 環境の数が限定されていますか? また、各環境ではどのような特別な変更が必要ですか?(※開発/テストと本番でそれぞれ異なるデータベースを使用する場合、プロジェクトはおそらくこのレベルです)
  • 非ポータブル
  • 他にユーザーがいますか? ポータブルにする必要がありますか?
 繰り返しますが、これらの質問に対する正しい答えはありません。しかし、プロジェクトはポータビリティのレベルを落とす方が簡単であること、およびビルドのポータビリティと柔軟性は反比例することの2点を覚えておきましょう。

Mavenで一般的なポータビリティ問題を解決する

 必要なポータビリティのレベルを定義したら、次の問題はプロジェクトをそのレベルまでまたはそのレベル以上に上げることです。皆さんのプロジェクトが自己完結型で、ユーザーが修正を加えたり標準Maven以外のものをインストールしたりせずにそのプロジェクトをビルドして実行できるのであれば、もう何も言うことはありません。皆さんのプロジェクトは既にワイドなポータビリティを実現しているので、ここで読むのを止めてかまいません。しかし、重要なプロジェクトである場合は、このまま続けてお読みださい。

systemスコープを回避する

 dependency要素では、次のようなprovidedスコープとsystemスコープを回避します。

<dependency>
  <groupId>com.closedsource</groupId>
  <artifactId>sometool</artifactId>

  <version>1</version>
  <scope>system</scope>
  <systemPath>/usr/lib/sometool.jar</systemPath>

</dependency>

 systemスコープを回避できない場合は、systemPathのプロパティを使います。これで、ビルド環境ごとにそのプロパティを設定/変更することができます。ただし、一番良い手段は、dependencyをインハウスのMavenリポジトリ(以下参照)にデプロイし、そのdependencyを標準スコープとして使う方法です(前述のステートメントについての詳細は、「補足説明5 絶対値をグループ化する」を参照してください)。

補足説明5 絶対値をグループ化する
 dependencyをインハウスのMavenリポジトリにデプロイし、そのdependencyを標準スコープとして使いたい場合は、プラグイン構成で絶対パスをハードコーディングしないようにしてください。例えば、JBossプラグインでは、JBossインストールを指すようにjbossHomeディレクトリを構成する必要があります。ここで役に立つのがプロパティです。
  <build>

    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>jboss-maven-plugin</artifactId>

        <configuration>
          <jbossHome>${jboss.home}</jbossHome>
        </configuration>
      </plugin>

    </plugins>
  </build>
  ...
  <properties>
    <jboss.home>${env.JBOSS_HOME}</jboss.home>

  </properties>
</project>
 これにより、プラグイン構成全体をオーバーライドしなくても、パスをprofileのproperties要素(または*.propertiesファイル)で簡単に変更することができます。
<profiles>
  <profile>

    <id>my-jboss</id>
    <properties>
      <jboss.home>${user.home}/jboss</jboss.home>

    </properties>
  </profile>
</profiles>
 これで、すべての絶対値をproperties要素という1つの場所から変更できるようになります。

フィルタを活用する

 フィルタは積極的に使用しましょう。Mavenではフィルタを使用することで、プロパティの置き換え(ビルドライフサイクルでは*-processフェーズでマークされます)を外部化し、移動しやすく構成可能なpropertiesファイルにすることができます。次のように、ビルド内でフィルタ処理する必要がある標準Javaのpropertiesファイルのリストを追加するだけです。

<filters>
  <filter>datasource.properties</filter>
</filters>

 本稿のサンプルプロジェクトでは、「datasource.properties」ファイルは基本ビルドディレクトリ(${buildDir})内にあり、「jdbc.url」に関する「名前=値」のペアを含んでいます。

jdbc.url=jdbc:driver://localhost/myDB

 リソースをフィルタ処理する場合、プロジェクトは一致するすべてのプロパティ名を対応する値に置き換えて、フィルタリストを取り入れます。フィルタ処理対象のリソースの定義にはresourcesビルド要素を使います。例えば、次のブロックでは、プロジェクトにフィルタ処理する必要があるXMLリソースがあることと、結果を「META-INF」ディレクトリに挿入することが指定されています。

<resources>

  <resource>
    <filtering>true</filtering>
    <directory>src/main/resources</directory>
    <targetPath>META-INF</targetPath>

    <includes>
      <include>*.xml</include>
    </includes>
  </resource>

</resources>

 サンプルプロジェクトの例を実行するには、コマンドラインでprocess-resourcesフェーズを実行します。これにより、次の「datasource.xml」リソースファイルが、

<datasource>
  <jdbc-url>${jdbc.url}</jdbc-url>

</datasource>

 次のように変換されます(「target/META-INF」ディレクトリ内)。

<datasource>
  <jdbc-url>jdbc:driver://localhost/myDB</jdbc-url>

</datasource>

プロファイルによる環境的なポータビリティ

 原則として、環境ごとに1つのプロファイルを作成するようにしてください。ビルドの環境タイプが5つを超える場合を除き、プロファイルはPOMに入れることをお勧めします。こうしておけば、コマンドラインで-P引数を指定して必要なプロファイルをアクティブにすることができます。次のようにhelpプラグインを使ってどのプロファイルが現在アクティブであるかをテストすることができます。

mvn help:active-profiles

 環境の変更は「settings.xml」ファイルを利用すればもっと簡単になります。サンプルプロジェクトには、env-dev、env-test、env-prodの3つのプロファイルが入っています。env-testプロファイルをテスト環境で常にアクティブしておきたい場合は、次のようにその環境の「settings.xml」ファイルにactiveProfileを追加します。

<settings>
  ...
  <activeProfiles>
    <activeProfile>env-test</activeProfile>

  </activeProfiles>
</settings>

 すべての環境別プロジェクトで、テストプロファイルにenv-testという名前を付けます。このプロファイルがない場合は、activeProfile行が無視されるだけです。サンプルプロジェクトには「settings.xml」ファイルが入っているので、自由に試してみてください。

プロファイルの増加に対応する

 プロファイルがもっと増えた場合はどうしたらよいでしょうか。プロジェクトによっては、複数のクライアント、場合によっては数百ものクライアントに合わせて、微妙なビルド変更が必要になることがあります。この場合に実行すべきことは、必要なビルド時にコピーできる「profiles.xml」ファイルの作成です。「profiles.xml」ファイルは「pom.xml」のprofiles要素とまったく同じで、1つ以上のprofile要素を含みます。例えば、次のような1つ目のクライアント向けのプロファイルがあるとします。

<profiles>
  <profile>
    <id>client-0001</id>
    <activation>
      <activeByDefault>true</activeByDefault>

    </activation>
    <properties>
      <!-- The client loves blue -->
      <css.pref>blue.css</css.pref>

      <!-- They want standard pkg -->
      <module>default</module>
   </properties>
  </profile>

</profiles>

 「profiles.xml」ごとに1つのプロファイルを作成し、それをactiveByDefaultにします。この存在そのものによって、プロファイルがビルドで利用されることが保証されます。前述の「profiles.xml」ファイルが基本ベースディレクトリ内にある場合にhelp:active-profilesを実行すると、以下が出力されます。

The following profiles are active:
 - client-0001 (source: profiles.xml)

プロパティではなくプロファイルを使う

 このアドバイスは、ワイドなポータビリティのオープンソースプロジェクトやプラグインプロジェクトではなく、環境が固定されているインハウスのプロジェクト向けです。

 ここでお勧めする簡単な作業は、プロファイルが1つのプロパティからのみ成り立っている場合でも、コマンドラインプロパティを渡すのではなく、環境プロファイルを作成することです。この背後にある論理は単純です。例えば、環境に対し次のようなプロファイルを作成するとします。

<profiles>
  <profile>
    <id>env-test</id>

    <properties>
      <install.location>/testbox/app</install.location>
    </properties>
  </profile>

</profiles>

 この場合、コマンドラインでアクティベーションを行うには次のように指定します。

mvn install -P env-test

 次のように指定してはなりません。

mvn install -Dinstall.location=/user/local/test

 プロパティをもう1つ追加する必要がある場合を想像しましょう。手動によるプロパティの設定は長くなりますが、プロファイル化したPOMコマンドラインは固定されているので、将来的にプロパティをいくつ追加しても変わりません。

mvn install -Dinstall.location=/user/local/test -Dnew.prop=true

 これは、Continuumのような継続的な統合サーバーを使う場合に重要になります。

プロジェクト構造の問題を回避する

 maven-antrun-pluginを介して大量のAntコードをPOMに注入することは、非ポータブルなプロジェクトでよく見られる光景です。一般に他のMavenプラグインでは要件を満たさないことが分かったら、まずプロジェクト構造を調べることが賢明です。

 プロジェクト構造を調べたところ、Mavenの非ポータビリティのもう1つの厄介な面が見つかりました。プロジェクトのネストです。例えば、次のようにEARにWARがネストされているとします。

myEar
  pom.xml
  META-INF/application.xml
  myWar
    src/MyServlet.java
    WEB-INF/web.xml

 Maven以前は、これはWARから成るプロジェクトを1つのEARでセットアップする一般的な方法でした。Antは、構造をまったく強要しない点が受け入れられていました。このような構造をMavenに持ち込み、組み込みのAntやmaven-assembly-pluginを使ってプロジェクトをビルドしようとする人もいます。例えば、1人のユーザーに対してこのようなプロジェクトを作成したとします。その後、異なるEAR構成を必要とする新しいユーザーが出てきました。WARは論理的には別個のプロジェクトですが、これを別のEARに移すのは非常に難しいことがわかっています。このプロジェクトを新しいユーザーに移植できる可能性は限られています。

 これは、Mavenの非標準のプロジェクト構造を強制的にMavenのフレームワークにしようとしている例です。こうした特定の例では、次のようにEARとWARを別々のプロジェクトに分ける必要があります。

myEar
  pom.xml
  src/main/resources/META-INF/application.xml
myWar
  pom.xml
  src/main
    java/MyServlet.java
    resources/WEB-INF/web.xml

 新しいユーザーに新しいEARを割り当てることは、何の問題もありません。myWarに対する依存性を持つ新しいEARプロジェクトを追加するだけです。心配無用です。覚えておけば役に立つでしょう。

独自のパブリックなリポジトリを作成する

 Mavenのセントラルリポジトリ以外のリポジトリに依存するプロジェクトの場合は、独自のパブリックなリポジトリを作成することを検討しましょう。このためには、パブリックのWebサーバーと、そのWebサーバーのファイルシステムにファイルをデプロイするためのメカニズム(FTPサーバーなど)、そしてPOMの若干の変更が必要です。最適なトランスポートメカニズムのインストールとセットアップ方法を説明したWeb関係の記事はたくさんありますが、この例ではWebDAVを使ってプロジェクトのアップロードを受け入れています。サーバーを構成したら、すべてのプロジェクトの継承元となる親POMを作成します。これで、デプロイメントはかなり楽になります。親POMに次のブロックを追加します。

<project>
  <artifactId>my-parent</artifactId>

  ...
  <build>
    <extensions>
      <extension>
        <groupId>org.apache.maven.wagon</groupId>
        <artifactId>wagon-webdav</artifactId>

        <version>1.0-beta-1</version>
      </extension>
    </extensions>
  </build>

  <distributionManagement>
    <repository>
      <id>codehaus-mojo</id>
      <name>Repository Name</name>

      <url>dav:https://dav.codehaus.org/repository/mojo/</url>
    </repository>
  </distributionManagement>
</project>

 URLのプレフィクスには、サポートされているWagonプロバイダのいずれか、つまりMavenが正しいリポジトリにファイルをトランスポートする場合に使うメカニズムを指定します(サポートされているプロバイダの種類については、ここをクリックしてください)。プロバイダの指定に加えて、使用するトランスポートメカニズムに対応するビルド拡張も追加する必要があります。この場合はWebDAVなので、wagon-webdavを追加しました。

 このサーバーにビルドをデプロイすることができるユーザーを制御するには、中心となる開発者にユーザー名を割り当てます。各ユーザーは、Mavenのインストール構成ディレクトリまたはローカルリポジトリディレクトリ下にある各自の「settings.xml」ファイルに、対応するリポジトリIDを指定することができます。

<settings>
  ...
  <servers>
    <server>

      <id>codehaus-mojo</id>
      <username>joe</username>
      <password>c4ntGuessThi5</password>

    </server>
  </servers>
  ...
</settings>

 このように開発者のローカル設定に変更を加える必要はありますが、ポータビリティには影響しません。心配な点は、クライアントビルダがローカルで変更を行わずにビルドとインストールを実行できるかどうかだけです。これは、彼らのためにリポジトリへのデプロイを簡単にする必要がある、という意味ではありません。

 他のデプロイ済みのプロジェクトに依存するプロジェクトについては、次のようにrepository要素を介して、リポジトリのパブリックな性質を追加することができます(Apache HTTP ServerなどのシンプルなWebサーバーを用いてパブリックにします)。

<project>
  ...
  <repositories>
    <repository>
      <id>codehaus-mojo</id>

      <url>http://repository.codehaus.org/org/codehaus/mojo/</url>
    </repository>
  </repositories>
</project>

 これでプロジェクトのポータビリティはワイドになりました。単なるインハウスのポータビリティにしたい場合は、ネットワークアクセスを制限して、リポジトリを利用するための「会員制クラブ」を設けます(必要なのは、秘密のハンドシェークだけです)。

市販のライセンス付きリモートリポジトリをインハウス化する

 ライセンス問題のためにプロジェクトをポータブルにできず、チームが成果物を手動でダウンロードしてインストールせざるを得ないこともあります。通常ならこれによってプロジェクトは非ポータブルの穴に落ちてしまいますが、Mavenではこの問題を単なる小さな頭痛の種程度に抑えています。例えば、「sometool.jar」というクローズドソースのJARのライセンスを持っているとします。これを次のようにインハウスのリポジトリ内にインストールすることで、他のMavenの成果物とまったく同じように他の社員もそのJARにアクセスできるようになります。

mvn deploy:deploy-file -DgroupId=com.closedsource -DartifactId=sometool
 -Dversion=1.0 -Dpackaging=jar -Dfile=sometool.jar -DgeneratePom=true

 -Durl=scp://inhouse/maven -DlocalRepository=inhouse

 これで、非ポータブルなプロジェクトが、ライセンス制限を受けてはいますがインハウスのポータビリティを持つプロジェクトになります。

javax.*を取得する

 従来のjavax.*パッケージはすべて、ライセンス制約のためにSunのWebサイトから手動で成果物をダウンロードしてインストールする必要がありましたが、もうその必要はありません。java.netで、javax.mail、javax.persistenceなどのいくつかのパッケージを含むパブリックなMaven 1.xリポジトリと2.xリポジトリが作成されました。どちらのリポジトリにも、プロジェクトのPOMに次のブロックを追加することでアクセスできます(Maven 1.xリポジトリのlayout要素に注意してください)。

<repository>

  <id>java.net</id>
  <url>https://maven-repository.dev.java.net/nonav/repository</url>
  <layout>legacy</layout>

</repository>
<repository>
  <id>maven2-repository.dev.java.net</id>
  <name>Java.net Repository for Maven</name>

  <url>https://maven2-repository.dev.java.net/nonav/repository</url>
</repository>

 これで、email APIを使用する非ポータブルなプロジェクトを、手動インストールの必要がないワイドなポータビリティを備えたプロジェクトにすることができます。

ポータビリティの夢

 Mavenのおかげで、ビルドプロセスそのものの標準化を始めることができるようになりました。完全ではないものの、MavenはJava開発の大きな躍進であり、純粋でシンプルなポータビリティの夢を現実のものにしてくれます。

著者紹介

Eric Redmond(Eric Redmond)
数百万ドルの価値(と百万行のコード)を持つJava EEプロジェクトのビルドアーキテクトだったが、現在は4人から成るチームのシニアエンジアとして活躍中。余暇には途方もない方法でJavaとRubyを組み合わせることを楽しんでいる。

プリンター用
記事を転送
この記事をクリップ!
【特別連載企画】大艦巨砲主義にして卓越したレスポンス--GALAXY S II WiMAX
【特別連載企画】大艦巨砲主義にして卓越したレスポンス--GALAXY S II WiMAX 1月20日より販売が開始されたサムスン製スマートフォン「GALAXY S II WiMAX」。カタログスペックでは、他メーカーのハイエンド機と同じように見えても、実際に使うと卓越したレスポンスに驚かされる。
⇒詳細記事はこちら
⇒連載記事一覧はこちら
注目のトピックス
最新コラム一覧
百式のネットビジネス研究
百式のネットビジネス研究
次のフライトでお好みの座席が空いたら教えてくれる「Expert Flyer」
アウンのグローバルマーケティング動向
アウンのグローバルマーケティング動向
Web プロモーションにおいて大切なこと―年度末編―
週刊-サイト別アクセス状況データ
週刊-サイト別アクセス状況データ
12月の主婦層、ベルメゾンが首位を維持(VRI 調査)
多言語×Web×海外マーケティング情報
多言語×Web×海外マーケティング情報
海外発、注目 AR プロモーション
エンジニア転職ノウハウ開発室
エンジニア転職ノウハウ開発室
楽天が目指す変革──Globalization、Agile、Big Data
中国・台湾ネットビジネス情報最前線
中国・台湾ネットビジネス情報最前線
中国から Web を見てもらいたいならば
マーケティングに活用できる最新トレンド
マーケティングに活用できる最新トレンド
改めて、「導線」最適化に目を向ける
次世代マーケティングチェーンの視点
次世代マーケティングチェーンの視点
ソーシャル時代における BtoC 型 Eコマース成功のポイント
Copyright 2012 internet.com K.K. (Japan) All Rights Reserved.