Java EEのearファイル形式はMavenの天敵

Ant + Ivy vs Maven - 達人プログラマーを目指して
で、AntとMavenの比較を行いました。そこではビルド要件の複雑度からAntが有利な場合とMavenが有利な場合について分析しています。それに関連して、最近Maven地獄に陥っているプロジェクトに関わることになり、pomのリファクタリングを行っているのですが、その作業をしていてひとつ気づいた点としてJava EEのearファイル形式はMavenの天敵であるという点があったので紹介しておきます。
earファイル形式は、Java EEの最初のころからあった形式ですし、Mavenでもしっかりとサポートしてくれて当然という期待があるのですが、意外にも現状サポートが不十分で、いろいろと問題があるということがわかりました。

ear内のモジュール間でのjarファイルの共有が困難

まず、第一にear内に複数のwarやrarなどのモジュールが含まれているようなケースで、jarファイルの共通化が極めて困難なことがあります。ear内でのjarファイルの共通化については、weblogicのAPP-INFディレクトリーやManifestクラスパスを使った方法など、以前から可搬性の少ない方法が使えたのですが、Java EE5からはear内の任意のディレクトリーをライブラリー用のjar格納ディレクトリーとして定義することが可能です。ところが、Mavenで何も考えずにmaven-ear-pluginでearファイルを作っても、そのようなjarファイルの共通化は当然されないため、同じjarファイルが複数のモジュール内に格納されてしまい、大変巨大なearが出来上がってしまいます。特に、warファイルに関してはSkinny war作成の問題として知られており、昨年にリリースされたmaven-war-pluginの2.1以降で、一応対応方法が追加されています。
Apache Maven WAR Plugin – Creating Skinny WARs
しかし、上記の対応をしても、m2eclipseのバグでeclipse内で正しくクラスパスが設定されないという問題があり、結局不本意ながら*1providedな依存関係を追加しまくるという対処が必要になります。また、そもそも、rarファイルではそのようなサポートすらされていないようなので、やはり、providedな依存関係を追加する必要があります。
MavenのSkinny war問題については、以下に詳しくまとめられています。
http://docs.codehaus.org/display/MAVENUSER/Solving+the+Skinny+Wars+problem
また、以下の記事のように最近でもこの問題に対してさまざまな試みがあるようですが、どれもいまひとつな感じです。
DRY and Skinny War - DZone Java

eclipseWTPとの相性が非常に悪い

m2eclipseとearファイルとの相性の問題が未だに解決されていないようであり、eclipse上からデプロイをかけると、期待されるファイルが正しく生成されず、デプロイできません。結局、外部でmvn packageなどを呼び出してearファイルを作成してからデプロイするという処置が必要になるようです。結果としてホットデプロイのようなことも困難になります。
Log in - Sonatype JIRA
Log in - Sonatype JIRA

NetBeansの場合はどうなのか試していませんが、少なくともeclipse上でearを使うようなプロジェクトでMaven化を行うと開発効率が大きく低下する可能性があるため注意が必要だと思います。もちろん、「earなんて複雑な形式は使わないよ」という幸せなプロジェクトでは問題ないのですが、EJBの採用が決定していたり、rarを使わないといけないプロジェクトなどでearを使わなくてはならないような場合は、それでもMavenを使うべきかどうか検討した方がよいでしょう。この場合プロジェクトにAnt使いがいるのならAntを使った方が無難かもしれません。*2

*1:これは本来のprovidedの用法ではないはずであくまでもワークアラウンドの色が強い。

*2:Springのビルドシステムがそうしているように、Antを使う場合でもディレクトリー構造をMavenの規約にそろえておくのはプラクティスとしてはよい習慣だと思います。