Spring BootでWARファイルを作成してTomcatへデプロイする方法

Spring Bootでwarを作成してTomcatへデプロイする方法です。

Spring BootでWARファイルを作成してTomcatへデプロイする方法

Spring Boot では、開発効率の向上のため、Tomcat が組み込まれております。そのため、jar ファイル単独で動作します。サーバーで jar をサービス登録し、Apache と連携すれば動きます。デプロイ不要で、クラウド時代にマッチした構成なのだと思います。しかし、本番環境は既に別の Tomcat があり、そっちで稼働させたいなんてニーズ多いんじゃないでしょうか。私のクライアントもこのような環境になっています。多くの企業がそういった状況にあるのではないかと思います。

別の Tomcat で動作させるには war ファイルを作成してデプロイする必要があります。

今回は Spring Bootでwarファイル作成から、既存Tomcatへのデプロイまで を紹介します。

開発中は Spring Boot 組み込み Tomcat を使って、テスト環境や本番環境は別 Tomcat にデプロイしたいって方のお役に立てればうれしいですね。


環境

Spring BootでWARを作成

まず、pom.xml の packaging を jar から war に変えます。

<packaging>war</packaging>

次に、下記の dependency を追加します。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
  <scope>provided</scope>
</dependency>

ポイントは scope を provided にすることです。Tomcat を外に追い出す感じですかね。

pom.xml ファイルを保存すると、下記のようなエラーが出ました。

Spring Boot 動的Webモジュール3.1はJava1.7またはそれ以降を要求します。

動的 Web モジュール 3.1 は Java 1.7 またはそれ以降 を要求します。はて? Java は8だし、ビルドパスも Java 8 なのに??

実は Eclipse で Maven プロジェクトを作成した場合、デフォルトで JRE システムライブラリが 1.6 になります。[プロジェクト]-[プロパティ]-[ビルドパス]で 1.8 に変更しても、一旦解決したように見えて、またすぐに戻ってしまいます。

この場合、pom.xml で、ビルドする JDK を明示的に指定すれば解決できます。

下記を追記しましょう。

<properties>
  <java.version>1.8</java.version>
</properties>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <source>${java.version}</source>
        <target>${java.version}</target>
      </configuration>
    </plugin>
  </plugins>
</build>

java.version を指定することで、maven.compiler.source と maven.compiler.target の指定が不要になります。failOnMissingWebXml は指定しなくても動作したので記述していません。

全体の pom.xml はこんな感じです。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>helloworldboot</groupId>
  <artifactId>springbootapp</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>springbootapp</name>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.1.RELEASE</version>
  </parent>
  <properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.5</thymeleaf-layout-dialect.version>
    <thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
    <thymeleaf-extras-data-attribute.version>2.0.5</thymeleaf-extras-data-attribute.version>
    <thymeleaf-extras-java8time.version>3.0.0.RELEASE</thymeleaf-extras-java8time.version>
  </properties>
  <build>
    <finalName>springbootapp</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>${java.version}</source>
          <target>${java.version}</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
    </dependency>
  </dependencies>
</project>

最終的なファイル名は springbootapp.war になるよう、finalName を追記しています。

次に App クラスを変更します。

このクラスをエントリポイントとし、 SpringBootServletInitializer クラスの継承と、configure メソッドを override します。

package springbootapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
public class App extends SpringBootServletInitializer {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(App.class);
  }
}

pom.xml を右クリックで Maven clean install を実行しましょう。

Spring Boot Maven clean installを実行

war ファイルが出来上がります。

Spring Boot warファイル出来上がり

・・・と、ここでよくログを見てみると、「groovy-2.4.7.jarの読込みエラー」なるものが出ていました。

[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ springbootapp ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to C:/Eclipse/4.6/workspace/springbootapp/target/classes
[WARNING] C:/Users/(ユーザー名)/.m2/repository/org/codehaus/groovy/groovy/2.4.7/groovy-2.4.7.jarの読込みエラーです。invalid LOC header (bad signature)

調べてみると、「invalid LOC header (bad signature)」は、ファイルが壊れている時に起こるエラーのようです。

maven - spring error during build - Stack Overflow

なので Groovy 公式サイトからダウンロードして、groovy-2.4.7.jar を上書きします。

The Groovy programming language - Download

上書きしたら Maven clean install を再実行しましょう。これをやらないと Tomcat のデプロイに失敗します。

エラーが出ていない方は、読み飛ばしてください。

Spring BootアプリをTomcatへデプロイ

さてさて、いよいよ Tomcat へデプロイしますよ。

Tomcat は Maven ビルド時に設定した Java のバージョンと同じであることが前提です。違っていると正しく動作しません。先ほど pom.xml の properties に java.version を 1.8 と追記したので、Tomcat も Java8 で動作させましょう。コマンドプロンプトから起動する場合、JAVA_HOME に依存しますので注意してください。

Eclipse から起動する場合は、Tomcat Plugin の追加が必要です。メニューのヘルプから Eclipse マーケットプレースを起動し、Tomcat Plugin と入力します。ここでは Eclipse Tomcat Plugin 9.1.2 をインストールしました。

Eclipse Tomcat Plugin 9.1.2をインストール

target ディレクトリ配下に .war ファイルを Tomcat インストールディレクトリ配下の webapp ディレクトリにコピーします。Tomcat を起動すると、勝手に展開されて以下のように war ファイルと同じフォルダが出来上がります。

Spring Boot warファイルをTomact webappディレクトリにコピー

Tomcat 8 以上を使っていて Web アプリケーションマネージャからデプロイすると失敗する場合があります。その場合「Tomcat 8/8.5 Manager Appからのwarデプロイに失敗する」を参考にしてみてください。

URL は「http://ホスト名:ポート/アプリ名/*」となります。.jar での実行時と形式が変わるので注意しましょう。

ここでは http://localhost:8080/springbootapp/ へアクセスします。

Spring Boot Webアプリへアクセス

おおお、表示されましたねー^^

まとめ

Spring Bootでwarを作成してTomcatへデプロイする方法を紹介しました。

groovy-2.4.7.jarの読込みエラー」でちょっとハマりましたけど、手順さえしっかりしておけば、特に迷うことなく作業が進められましたね。

しかし web.xml なしで Tomcat にデプロイしたら Filter したい場合はどうするのよ?って声が聞こえてきそうですね。確かにエンコーディングやロギングなんかは Filter 実装というのが定番でしたからね。この辺りは次回に紹介したいと思います。

おつかれさまでした。

この記事がお役に立ちましたら シェア をお願いいたします。