Spring Boot 組み込みのTomcatのバージョンを変更する

change-embedded-tomcat-version

Spring Bootでは組み込みのサーブレットコンテナが利用できます。
便利な機能ですが、実開発で利用する場合実際のプロダクション環境のバージョンのTomcatと併せたいという事があると思います。その手順に関して説明します。

はじめに

Spring Boot のファイルアップロードに関するエラーハンドリングを実装している際に、Spring Boot 組込みのTomcatでは上手く動作せず、Linux上のデプロイ環境に war デプロイして動かしたら、想定通りに動作するという問題に遭遇しました。

Spring Bootでは組込みのサーブレットコンテナ ( Tomcat、 Jetty ) 等を利用してWebアプリケーションを実行可能ですが、普通にSTS ( Spring Tool Suite ) を利用してプロジェクトを作成した場合、利用する Tomcat のバージョンを指定する事はできません。

ここでは組込みTomcatのバージョンを指定する方法に関して説明します。

環境

環境は以下です。

Spring Boot 1.3.5

既に 1.3.7が出てますけど...
※ビルドツールとして Maven を利用する方向で説明します。

手順

現バージョンの確認

Spring Boot にデフォルトで組み込まれている Tomcat のバージョンは、Spring Boot の起動時ログを見る事で確認できます。

2016-08-01 17:31:32.381 INFO  6672 [  restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-08-01 17:31:32.402 INFO  6672 [  restartedMain] o.apache.catalina.core.StandardService   : Starting service Tomcat
2016-08-01 17:31:32.407 INFO  6672 [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.33

1.3.5 の場合 Tomcat 8.0.33 が利用されているようです。

※spring-boot-starter-parent の parent である spring-boot-dependencies の pom.xml で定義されています。

設定方法

上記 spring-boot-dependencies の設定を上書き指定する事で組込み tomcat のバージョンを変更できます。

pom.xml の以下部分を変更 ( tomcat.versionを追記 ) します。

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.7</java.version>
	    <tomcat.version>7.0.54</tomcat.version>
	</properties>

ちなみに、spring-boot-dependencies のpom.xml には以下の設定が記載されています。tomcat.version の設定値はここで利用されます。

※当初以下の記載もプロジェクトのpom.xmlに記載が必要かと思って上書きしていましたが、tomcat.version だけ上書き設定すれば良い事に気づきました。

	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-core</artifactId>
		<version>${tomcat.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-el</artifactId>
		<version>${tomcat.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-jasper</artifactId>
		<version>${tomcat.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-logging-juli</artifactId>
		<version>${tomcat.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-websocket</artifactId>
		<version>${tomcat.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat</groupId>
		<artifactId>tomcat-jdbc</artifactId>
		<version>${tomcat.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.tomcat</groupId>
		<artifactId>tomcat-jsp-api</artifactId>
		<version>${tomcat.version}</version>
	</dependency>

pom.xml は Spring Boot のバージョン毎に異なるので、利用しているRELEASE Tag のspring-boot-dependencies でどう設定されているかを確認するのをお勧めします。

※1.3.5 なら https://github.com/spring-projects/spring-boot/blob/v1.3.5.RELEASE/spring-boot-dependencies/pom.xml

動作確認

設定が完了したら、Spring Boot アプリケーションを再起動します。
バージョンを変更した場合、組込みTomcatのjar等必要なライブラリが Maven Repositoryから取得された後、起動が行われます。

起動ログにてTomcatのバージョンが変更されている事を確認できると思います。

まとめ

はじめに で書いた、開発環境とデプロイ環境での動きの違いに関してですが、Tomcatのバージョンを合わせることで、この問題も解消する事ができました。

通常、プロダクション環境のTomcatバージョンが決まっている場合、開発環境のバージョンもこれに併せる方がよいと思います。

spring-boot-dependencies の pom.xml には Tomcat 以外にも様々な依存ライブラリのバージョンが定義されているので、「バージョン違いによって、これまで作成したコンポーネントが流用できない」といった場合にも、バージョン指定で解決できないかどうか確認してみるといった事も可能かもしれません。 ( ライブラリ間の依存関係もあるので、単純に置き換え可能かどうかは判らないが )