Maven War Plugin:warファイル生成のカスタマイズ

はじめに

こんにちは、Anti-Pattern Inc.の塚本です。

参画したプロジェクトで、Mavenアプリケーションでアーカイブを作成したくないご要望があったので、その際に調べたtipsを共有します。

SampleAppをmavenでpackageする場合

SampleAppというアプリケーションをmavenでpackageする場合、このようなディレクトリが生成されます。今回は、コンパイルだけして、SampleApp.warを作らない設定方法について説明します。

プロジェクトディレクトリ
 - target
   SampleApp
   SampleApp.war
   classes
   generated-sources
   maven-archiver
   maven-status

Maven の Package フェーズとは

Maven のビルドライフサイクルには複数のフェーズがあります。このフェーズでは、コンパイルされたコードやリソースファイルをディストリビューション形式(JAR、WAR など)にパッケージングします。

mvn package コマンドを実行すると、以下のようなことが行われます:

  • ソースコードのコンパイル
  • テストの実行
  • プロジェクト成果物(アーティファクト)のパッケージング

pom.xmlのpackagingタグの設定によりますが、Web アプリケーションの場合、この成果物は通常 WARファイルとなります。

maven-war-plugin について

maven-war-plugin は、Java Web アプリケーションを WAR ファイルにパッケージングするための Maven プラグインです。以下は、今回対応したpom.xmlのサンプルです。

<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <webResources>
                    <resource>
                        <directory>${project.basedir}/src/main/webapp</directory>
                    </resource>
                </webResources>                    
            </configuration>
        <!-- コメントインするとwarファイルを作成しない
            <executions>
                <execution>
                    <id>default-war</id>
                    <phase>none</phase>
                </execution>
                <execution>
                    <id>war-exploded</id>
                    <phase>package</phase>
                    <goals>
                        <goal>exploded</goal>
                    </goals>
                </execution>
            </executions>
        -->
        </plugin>            
    </plugins>
</pluginManagement>

configuration 要素

  • failOnMissingWebXml: false に設定することで、web.xml ファイルが存在しなくてもビルドが失敗しないようにします。Servlet 3.0 以降では web.xml が必須ではなくなったため、この設定が便利です。
  • webResources: WAR ファイルに含めるリソースを指定します。
    • resource: リソースの場所を指定します。
    • directory: リソースが格納されているディレクトリのパスを指定します。この例では ${project.basedir}/src/main/webapp を指定しています。

executions 要素(コメントアウト部分)

この部分はコメントアウトされていますが、コメントインすると以下の動作をします:

  • default-war 実行を無効化(phasenone に設定)
    • 通常の WAR ファイル生成プロセスを無効にします
  • war-exploded 実行を有効化
    • package フェーズで exploded ゴールを実行します
    • exploded ゴールは展開された状態(ディレクトリ構造)の WAR を生成します
    • これにより、WAR ファイル(*.war)は作成されず、展開済みディレクトリのみが生成されます

exploded WAR とは

展開された(exploded)WAR とは、圧縮された単一の WAR ファイルではなく、同じ内容がディレクトリ構造として展開された状態を指します。これには以下のようなメリットがあります:

  • 開発効率の向上: ファイルを変更した場合、WAR ファイル全体を再デプロイする必要がなく、変更したファイルだけを置き換えることができます
  • デバッグのしやすさ: 実行中のアプリケーションのファイルに直接アクセスできるため、問題の診断が容易になります
  • ホットデプロイの容易さ: 多くのアプリケーションサーバーでは、展開された状態のアプリケーションはホットデプロイ(再起動なしの更新)が容易です

今回は生成AIを使って調べたのですが、以下のサイトも参考にさせていただきました:

https://stackoverflow.com/questions/352612/how-to-get-maven-to-run-warexploded-but-not-warwar