maven-eclipse-plugin

id:ppoiさんにいろいろ教えてもらったので、メモっとく。

開発環境と本番環境が異なるのはよくあるケース(というかほとんど?)だと思う。

たとえば開発時はWTP+Tomcatを使っていてSeasarトランザクションマネージャを使うためJDBCドライバが必要だが、
本番ではWAS等の商用のAPサーバのデータソースを使うのでJDBCドライバが不要とか。Servlet APIとかもそう。

商用のAPサーバを開発者全員に用意するのはライセンス的に難しそうだし、かといって体験版だと使用期限の
問題がある。

仮に全員分用意できたとしても、マシンが重くなりそうだし。まあHot Deployがあるからいいじゃんという意見もありそうですが。。。

こういうケースでmaven-eclipse-pluginWTPのプロジェクトを生成している場合は、ちょっと面倒。

Servlet APIのようにscopeがprovidedの場合、

mvn eclipse:eclipse

とやると、.classpathのclasspathentryには記述されるがorg.eclipse.wst.common.commponentのdependent-moduleには
記述されないため、WTPの実行時にNoClassDefFoundErrorになる。

scopeをruntimeにするとdependent-moduleに記述されるがwarを生成した際にWEB-INF/libにjarが含まれてしまう。

回避策としては、profileを使うこと。
pom.xmlを以下のようにして、

<profiles>
  <profile>
    <id>eclipse</id>
      <dependencies>
        <dependency>
          <groupId>org.apache.geronimo.specs</groupId>
          <artifactId>geronimo-j2ee_1.4_spec</artifactId>
          <version>1.0</version>
          <type>jar</type>
          <scope>provided</scope>
        </dependency>
(略)

mvn -P eclipse eclipse:eclipse

とする。こうすれば、Eclipse上での実行は問題ない。warを作成するときは、profileをオフにすればいい。

ちなみにmaven-eclipse-pluginのソースを見ると、scopeがprovidedの場合はdependent-moduleには
記述しないようにしている。

以下のように変更すれば、scopeがprovidedでもdependent-moduleに記述されるようになる。

Index: main/java/org/apache/maven/plugin/eclipse/writers/wtp/AbstractWtpResourceWriter.java
===================================================================

@@ -277,7 +277,7 @@

// NB war is needed for ear projects, we suppose nobody adds a war dependency to a war/jar project
// exclude test and provided and system dependencies outside the project

  • if ( ( !dep.isTestDependency() && !dep.isProvided() && !dep.isSystemScopedOutsideProject( project ) ) &&
  1. if ( ( !dep.isTestDependency() && !dep.isSystemScopedOutsideProject( project ) ) &&

( Constants.PROJECT_PACKAGING_JAR.equals( type ) || Constants.PROJECT_PACKAGING_EJB.equals( type ) ||
"ejb-client".equals( type ) || Constants.PROJECT_PACKAGING_WAR.equals( type ) ) ) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
{

ただJDBCドライバのようにscopeがruntimeの場合、開発時は問題ないが、
war作成時にWEB-INF/libにJDBCドライバが入っちゃう問題は
profileで回避するしかないような。まあ%TOMCAT_HOME%\common\libに最初からおいておくという手もありますが。

それとも、maven-war-pluginをいじれってか。。。
いやいやなんかオプションがあるのかな。

まあ私は手動でwar作り直したりしてましたけど。^^);

開発環境と本番環境が同じなら上記のような問題は発生しないですが(war作成もIDEからやる)、
Maven2の開発者達はそういうのが当たり前なのかな。