“`html

Gradleのwarプラグインとは?基本知識とJAR・WARの違い

warプラグインの役割と適用方法

GradleでWARファイルを作成するには、warプラグインを適用します。warプラグインはJavaプラグインを拡張したもので、Javaプラグインが提供するコンパイルやテストなどのタスクに加えて、WARアーカイブを生成するwarタスクを追加します。適用するには、ビルドスクリプトに以下のように記述します。

plugins {
    id 'war'
}

warプラグインを適用すると、JavaプラグインのデフォルトであるJARアーカイブ生成が無効化され、代わりにWARファイルが生成されるようになります。これにより、Webアプリケーションに必要な構成でパッケージングできます。(出典:Gradle公式「The War Plugin」)

WARファイルとJARファイルの違い

WAR(Web Application Archive)は、Java製Webアプリケーションをアプリケーションサーバにデプロイするための配布形式です。一方、JAR(Java Archive)は単一のJavaアプリケーションやライブラリをまとめる形式です。両者の主な違いを表で比較します。

項目 JAR WAR
対象 Javaアプリ、ライブラリ Webアプリケーション
実行方法 java -jarで実行可能な場合あり Tomcatなどのアプリケーションサーバにデプロイ
主要構成 CLASSファイル、META-INF/MANIFEST.MF WEB-INF/classes、WEB-INF/lib、web.xml、静的リソース
Gradle生成タスク jar war

WARはHTMLやCSS、JavaScript、JSP、サーブレットなど、Webアプリに必要な要素を標準的な構成でまとめます。JARがJavaランタイムで直接実行されるのに対し、WARはサーブレットコンテナ上で動作する点が大きな違いです。

WARファイルの標準構成と出力先

warプラグインは、プロジェクトにsrc/main/webappディレクトリを追加します。このディレクトリに配置したHTMLやCSS、JSP、WEB-INF/web.xmlなどのファイルが、WARアーカイブのルートにコピーされます。コンパイル済みのclassファイルはWEB-INF/classesに、依存ライブラリはWEB-INF/libに配置されます。

生成されるWARファイルの出力先はbuild/libs/です。デフォルトのファイル名は<プロジェクト名>-<バージョン>.warとなります。この構成はJava EE / Jakarta EEの仕様で標準化されており、Gradleはこの仕様に従ってWARを生成します。

要点:warプラグインを適用するとwarタスクが追加され、src/main/webappの内容とコンパイル済みクラス、依存ライブラリを標準構成でまとめたWARファイルがbuild/libs/に生成されます。

WARファイルの作成手順とビルドコマンド

WARファイル作成の基本手順

GradleでWARファイルを作成する手順は、以下の3ステップです。まずビルドスクリプトにwarプラグインを適用し、次にsrc/main/webappディレクトリにWebリソースを配置し、最後にビルドコマンドを実行します。

  1. warプラグインの適用build.gradleまたはbuild.gradle.ktsid 'war'を追加する
  2. Webリソースの配置src/main/webappにHTML、CSS、JSP、WEB-INF/web.xmlなどを配置する
  3. ビルド実行gradle buildまたはgradle warを実行する

warプラグインはJavaプラグインを自動的に適用するため、Javaソースコードのコンパイルやテストも同時に実行されます。src/main/webappはWARのルートになるため、ここに配置したファイルがそのままアーカイブに含まれます。

ビルドコマンドの種類と使い分け

WARファイル生成に関連する主なコマンドは以下の通りです。目的に応じて使い分けます。

コマンド 実行内容 用途
gradle war WARタスクのみ実行 WARファイルだけを素早く生成したい場合
gradle build コンパイル、テスト、パッケージングを一括実行 通常のビルド。WARも生成される
gradle clean build buildディレクトリを削除してからビルド 古い成果物を確実に除去したい場合

gradle buildwarタスクを含むライフサイクル全体を実行します。一方gradle warはWAR生成のみを行うため、コンパイル済みのクラスが存在しない場合は依存関係に従って必要なタスクも実行されます。

Gradle Wrapperの利用推奨

Gradle公式は、システムにインストールしたGradleよりもGradle Wrapper(gradlew / gradlew.batの使用を推奨しています。Wrapperを使うと、プロジェクトごとにGradleのバージョンを固定でき、開発者全員が同じ環境でビルドできます。

既存プロジェクトでは、まずgradlewの有無とgradle-wrapper.propertiesに記載されたバージョンを確認します。Wrapperが存在する場合は、gradleではなく./gradlewでビルドを実行するのが基本です。これにより、CI環境でも同じバージョンのGradleを利用できます。(出典:Gradle公式「Gradle Wrapper Basics」)

要点:warプラグイン適用後はgradle warでWARのみ、gradle buildで全体をビルドできます。既存プロジェクトではGradle Wrapperの使用を確認しましょう。

warタスクのカスタマイズ方法とファイル名指定

アーカイブファイル名の変更

WARファイルの出力名を変更するには、warタスクのarchiveFileNameプロパティを設定します。Gradle 8系以降ではarchiveNameは廃止され、archiveFileNameが推奨されています。Groovy DSLでは以下のように記述します。

tasks.war {
    archiveFileName = 'myapp.war'
}

Kotlin DSLではarchiveFileName.set("myapp.war")を使用します。これにより、build/libs/myapp.warというファイル名で出力されます。バージョン番号を含めずに固定名にしたい場合や、デプロイ先の要件に合わせた名前にしたい場合に便利です。

webappディレクトリとリソースの追加

デフォルトのsrc/main/webapp以外のディレクトリをWARに含めたい場合は、fromメソッドを使用します。また、webInfブロックでWEB-INF配下に追加リソースを配置できます。以下はカスタマイズ例です。

tasks.war {
    webAppDirectory = file('src/main/webapp')
    from('src/rootContent')
    webInf { from('src/additionalWebInf') }
    webXml = file('src/someWeb.xml')
}

webAppDirectoryはWebアプリソースの場所を変更し、fromはアーカイブルートに追加するリソースを指定します。webXmlプロパティを使うと、特定のweb.xmlをWEB-INF/web.xmlとして配置できます。これらの設定により、プロジェクト固有の構成に対応できます。(出典:Gradle公式「The War Plugin」)

providedCompileとprovidedRuntimeの使い方

warプラグインはprovidedCompileprovidedRuntimeという2つの依存関係構成を追加します。これらはコンパイル時や実行時にはクラスパスに含まれますが、WARファイルには含まれません。典型的な例はサーブレットAPIです。アプリケーションサーバ側が提供するため、WARに含めると競合の原因になります。

dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:4.0.1'
}

注意点として、provided構成は推移的(transitive)です。providedCompileに追加した依存関係の推移的依存関係もWARに含まれません。推移的な動作を避けたい場合は@jar表記を使用します。

要点:warタスクはarchiveFileNameでファイル名を変更でき、fromwebInfでリソースを追加できます。providedCompile/providedRuntimeでWARに含めない依存関係を指定可能です。

Spring BootでのbootWarとwarの使い分け

bootWarタスクとwarタスクの役割の違い

Spring BootプロジェクトでWARを作成する場合、bootWarタスクが実行可能WARを生成します。Spring Boot Gradleプラグインを適用すると、標準のwarタスクは無効化され、代わりにbootWarタスクがWAR生成を担当します。warタスクはbootWarから利用されるため、直接実行する必要はありません。

タスク 生成物 実行方法
bootWar 実行可能WAR java -jarで直接実行可能
war (bootWar実行時の内部処理) 通常は直接実行しない

gradle buildを実行すると、実行可能WARが生成されます。プラグインの適用はid 'org.springframework.boot'id 'war'の両方を指定します。(出典:Spring公式「Packaging Executable Archives」)

従来のサーバにデプロイ可能なWARを作る3つの条件

Spring BootアプリをWARとしてTomcatなどの従来のアプリケーションサーバにデプロイするには、以下の3つの手順が必要です。

  1. メインクラスをSpringBootServletInitializerを継承させるconfigureメソッドをオーバーライドしてアプリケーションソースを指定します
  2. warプラグインを適用するid 'war'をビルドスクリプトに追加します
  3. 内蔵サーブレットコンテナをprovidedRuntimeで宣言する:内蔵Tomcatがデプロイ先のサーブレットコンテナと競合しないようにします

3つ目の設定では、compileOnlyではなくprovidedRuntimeを使うことが推奨されていますcompileOnlyにはテストクラスパスに含まれないなどの制限があり、Webベースの統合テストが失敗する可能性があるためです。(出典:Spring公式「Traditional Deployment」)

WARデプロイ時の互換性と注意点

Spring Boot 3.x系のWARはJakarta EEベース(jakarta.*パッケージ)を使用するため、デプロイ先にはTomcat 10以上が必要です。Tomcat 9以前はjavax.*パッケージを使用しているため互換性がありません。デプロイ前に必ず対象サーバのバージョンを確認しましょう。

また、Spring WebFluxアプリはWARデプロイ非対応です。WebFluxはサーブレットAPIに依存せず、デフォルトで内蔵Reactor Nettyサーバにデプロイされるため、WAR形式でのデプロイはサポートされません。Spring MVCを使用している場合のみWARデプロイが可能です。(出典:Spring公式「Traditional Deployment」)

要点:Spring BootではbootWarが実行可能WARを生成します。従来サーバへのデプロイにはSpringBootServletInitializerの継承、warプラグイン適用、providedRuntimeでの内蔵Tomcat除外が必要です。

GradleとMavenのWAR作成コマンド比較

ビルドコマンドと出力先の違い

GradleとMavenでは、WARファイルを作成するコマンドと出力先が異なります。Gradleはwarタスク、Mavenはmaven-war-pluginを使用します。以下に主なコマンドを比較します。

操作 Gradle Maven
WARのみ生成 gradle war mvn package
全体ビルド gradle build mvn package
クリーンビルド gradle clean build mvn clean package
出力先 build/libs/ target/

重要な違いとして、Mavenのpackageフェーズはライフサイクルの一部としてコンパイルを自動で行います。そのため、mvn packageを実行すればWAR生成まで完了します。一方、Gradleのwarタスクは依存関係に従って必要なタスクも自動的に実行します。(出典:Maven公式「Apache Maven WAR Plugin – Usage」)

設定方法とprovidedスコープの対応関係

Gradleではビルドスクリプトにid 'war'を追加するだけでWAR作成が有効になります。Mavenではpom.xml<packaging>warに変更します。これによりmaven-war-pluginが有効になります。

WARに含めない依存関係の指定方法も対比できます。GradleのprovidedCompileprovidedRuntimeは、Mavenの<scope>provided</scope>に相当します。どちらもアプリケーションサーバが提供するライブラリ(サーブレットAPIなど)をWARから除外するために使います。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

両ツールともprovided系の依存関係は推移的です。推移的依存関係もWARに含まれないため、意図しない除外が発生しないよう注意が必要です。

MavenのWAR関連ゴールとGradleのタスク対応

Mavenにはwar:war以外にもWAR関連のゴールがあります。Gradleのタスクとの対応を理解すると、移行時に役立ちます。

Mavenゴール 用途 Gradleでの対応
war:war WARファイル生成 warタスク
war:exploded 展開されたWARを生成(開発時のテスト高速化) 専用タスクなし(warタスクの出力を展開する設定が可能)
war:inplace 展開版をsrc/main/webappに直接作成 専用タスクなし

war:explodedは開発時にサーバへのデプロイを高速化するために使われます。Gradleには同等の専用タスクは標準で用意されていませんが、warタスクのカスタマイズで対応できます。MavenからGradleへの移行時は、この対応関係を理解しておくとスムーズです。(出典:Maven公式「Apache Maven WAR Plugin – Usage」)

要点:Gradleはgradle war、Mavenはmvn packageでWARを生成します。Mavenのpackageフェーズはコンパイルを含むライフサイクルの一部である点、providedスコープの推移的な動作に注意が必要です。

“`