---
title: "Spring Bootの組み込みTomcat｜tomcat.versionでの版上げ・server.*設定・Jetty切替・WAR化の手順【4.1.2対応】"
url: "https://www.issoh.co.jp/tech/details/19273/"
published: 2026-11-03
updated: 2026-11-03
categories: ["Java"]
publisher: "株式会社一創"
---

# Spring Bootの組み込みTomcat｜tomcat.versionでの版上げ・server.\*設定・Jetty切替・WAR化の手順【4.1.2対応】

Spring Bootの組み込みTomcatは、アプリのjarの中に`tomcat-embed-core`というライブラリとして入っており、その版はSpring Bootが決めています。2026年11月3日時点で、Spring Boot 4.1.2が管理する版は11.0.27、3.5.16が管理する版は10.1.55です。この記事では、版が決まる仕組み、Tomcatの脆弱性が公表されたときに組み込み版だけを先に上げる`tomcat.version`の手順、`application.properties`の`server.*`で変えられる項目と既定値、Jettyへの差し替え、外部TomcatへのWARデプロイを選ぶ条件までを、コード例つきで整理します。

## まとめ｜組み込みTomcatはSpring Bootの版に従わせて設定はプロパティで済ませる

組み込みTomcatの版は、Spring Bootを上げれば一緒に上がります。普段はこれで十分です。Spring Bootの修正版より先にTomcatの脆弱性が公表されたときだけ、`tomcat.version`プロパティで組み込み版を個別に上げ、次のSpring Bootの修正版が出たら上書きを外します。

設定は`server.port`や`server.tomcat.threads.max`などのプロパティで大半が足ります。足りない部分だけ`WebServerFactoryCustomizer`で書きます。単体Tomcatから移す場合は、タイムアウトの既定値とログの出力先が違う点に注意してください。

**新規開発は実行可能jarを標準にし、外部TomcatへのWARデプロイは既存の運用上の制約がある場合に限ります。**Undertowを使っていたアプリは、Spring Boot 4へ上げる前にTomcatかJettyへ移す必要があります。

## 組み込みTomcatが入る経路とSpring Bootが版を決める依存管理の仕組み

### Spring MVCのスターターから組み込みTomcatへ至る依存関係の経路

Spring MVCのアプリでは、`spring-boot-starter-webmvc`というWeb用のスターターを入れるだけで、`tomcat-embed-core`を含む組み込みTomcatが付いてきます。[組み込みWebサーバーのドキュメント](https://docs.spring.io/spring-boot/how-to/webserver.html)によると、サーブレット系のスターターは`spring-boot-starter-tomcat`を経由してTomcatを含みます。その先にあるのが`org.apache.tomcat.embed`グループの`tomcat-embed-core`・`tomcat-embed-el`・`tomcat-embed-websocket`の3つです。

スターター名はSpring Boot 4で変わりました。[4.0の移行ガイド](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide)では`spring-boot-starter-web`の代わりに`spring-boot-starter-webmvc`が示され、旧名は非推奨として当面残ります。経路は依存ツリーで確かめられます。

```
# Maven：組み込みTomcatがどのスターター経由で入っているかを見る
./mvnw dependency:tree -Dincludes=org.apache.tomcat.embed

# Gradle：実行時クラスパスで解決された版と、その理由を見る
./gradlew dependencyInsight --dependency tomcat-embed-core --configuration runtimeClasspath
```

出力に`spring-boot-starter-tomcat`が挟まっていれば標準の経路です。確認コマンドの読み方や本番のjarとの照合は[Tomcatのバージョン確認方法](https://www.issoh.co.jp/tech/details/19269/)で詳しく扱っています。

### Spring Boot 4.1.2と3.5.16のWebサーバー管理版の比較

Spring Bootは、検証済みの依存の版を`spring-boot-dependencies`というBOM（版の一覧表）にまとめています。版を書かずに依存を宣言すると、この表の値が使われます。公式の管理依存の一覧（[4.1.2](https://docs.spring.io/spring-boot/appendix/dependency-versions/coordinates.html)・[3.5.16](https://docs.spring.io/spring-boot/3.5/appendix/dependency-versions/coordinates.html)）から、Webサーバー関連を抜き出すと次のとおりです。

| ライブラリ               | Spring Boot 4.1.2 | Spring Boot 3.5.16 |
| ------------------- | ----------------- | ------------------ |
| tomcat-embed-core   | 11.0.27           | 10.1.55            |
| jetty-server        | 12.1.14           | 12.0.36            |
| undertow-core       | 管理対象外             | 2.3.24.Final       |
| jakarta.servlet-api | 6.1.0             | 6.0.0              |

Tomcat側の[対応表](https://tomcat.apache.org/whichversion.html)では、11.0系がServlet 6.1、10.1系がServlet 6.0に対応します。Spring Boot 4はTomcat 11、3.5はTomcat 10.1という組み合わせです。Spring Bootの各系列がいつまで修正版を出すかは[Spring Bootのバージョン一覧とサポート期限](https://www.issoh.co.jp/tech/details/5172/)、Tomcat系列の期限は[Tomcatのバージョン一覧とサポート期限](https://www.issoh.co.jp/tech/details/18728/)を見てください。

## Tomcatの脆弱性公表時に組み込み版だけを先に上げるtomcat.versionの手順

### Spring Bootの管理版がTomcatの修正版より遅れる場面の実例

Spring Bootの修正版は、Tomcatの修正版を取り込んでから出ます。その間は、Spring Bootを最新にしても組み込みTomcatが修正前の版のままです。

3.5.16が管理する10.1.55がその例です。Tomcatの[10.1系のセキュリティ情報](https://tomcat.apache.org/security-10.html)では、HTTP/2の非同期処理で応答を取り違えるCVE-2026-101356（重大度Important）の影響範囲が10.1.55〜10.1.60で、10.1.61で修正されています。HTTP/2を有効にしている3.5系のアプリは、この時点でSpring Bootの更新を待たずに組み込み版を上げる理由があります。

判定の手順は「版が影響範囲に入るか」「その機能を使っているか」の2段です。CVEごとの影響条件は[Apache Tomcatの脆弱性一覧と影響確認・対応手順](https://www.issoh.co.jp/tech/details/15405/)にまとめています。

### Mavenのpom.xmlでtomcat.versionを上書きする2通りの書き方

Tomcatの版を決めるプロパティ名は、[版プロパティの一覧](https://docs.spring.io/spring-boot/appendix/dependency-versions/properties.html)にある`tomcat.version`です。`spring-boot-starter-parent`を継承しているなら、[Mavenプラグインのドキュメント](https://docs.spring.io/spring-boot/maven-plugin/using.html)のとおり、プロパティを1行足せば3つの`tomcat-embed-*`がまとめて切り替わります。

```
<!-- pom.xml（spring-boot-starter-parent を継承している場合） -->
<properties>
  <tomcat.version>10.1.61</tomcat.version>
</properties>
```

親POMを使わず`spring-boot-dependencies`をBOMとしてimportしている構成では、このプロパティが効きません。同じドキュメントによると、上書きしたい依存を`dependencyManagement`の中で**BOMのimportより前**に書く必要があります。

```
<dependencyManagement>
  <dependencies>
    <!-- Spring Boot の BOM より前に書く（3つとも同じ版にそろえる） -->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>10.1.61</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-el</artifactId>
      <version>10.1.61</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-websocket</artifactId>
      <version>10.1.61</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>3.5.16</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
```

3つのうち`tomcat-embed-core`だけを上げると、ELやWebSocketのjarが旧版のまま混ざります。**上書きするなら3つを同じ版にそろえる**のが原則です。

### Gradleでの上書きとplatform方式でプロパティが効かない落とし穴

Gradleの書き方は、BOMの読み込み方で変わります。[Gradleプラグインの依存管理のドキュメント](https://docs.spring.io/spring-boot/gradle-plugin/managing-dependencies.html)によると、`io.spring.dependency-management`プラグインを使っていれば`ext`（Kotlin DSLは`extra`）でプロパティを設定できます。

```
// build.gradle（dependency-management プラグイン使用時）
ext['tomcat.version'] = '10.1.61'

// build.gradle.kts の場合
extra["tomcat.version"] = "10.1.61"

// Gradle の platform() で BOM を読んでいる場合はプロパティが効かない（build.gradle.kts の例）
configurations.all {
    resolutionStrategy.eachDependency {
        if (requested.group == "org.apache.tomcat.embed") {
            useVersion("10.1.61")
        }
    }
}
```

Gradle標準の`platform()`でBOMを読んでいる場合、同じドキュメントは`spring-boot-dependencies`のプロパティでは版を制御できないと明記しています。`ext`を書いても黙って無視されるので、上の`resolutionStrategy`でグループごと版を固定します。書いた後は前の章の`dependencyInsight`で、解決された版が10.1.61になったかを必ず見てください。

公式の警告は、上書きが互換性の問題を招く可能性を踏まえ、慎重な対応を促すものです。上書きは同じ系列内（10.1.xの中、11.0.xの中）のパッチ番号を上げる用途に限り、Spring Bootの次の修正版が同じ版以上を管理するようになった時点で外します。系列をまたいで10.1系から11.0系へ上げるのは、Spring Boot自体の版上げとして扱います。

## 組み込みTomcatのserver.\*による設定項目と既定値の調整方法

### 待ち受けポート・コンテキストパス・ランダムポートを変える基本設定

待ち受けポートの既定は8080で、`server.port`で変えます。[組み込みWebサーバーのドキュメント](https://docs.spring.io/spring-boot/how-to/webserver.html)によると、環境変数`SERVER_PORT`でも指定でき、`0`にするとOSが空いているポートを選びます。`-1`はHTTPの待ち受け自体を止める指定です。

```
# application.properties
server.port=8081
# アプリを /app 配下で公開する
server.servlet.context-path=/app
# 停止時は処理中のリクエストを待つ（4.1.2 の既定は graceful）
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s
```

コンテナで動かす場合は、ポートをイメージに焼き込まず環境変数で渡すと、同じjarを複数の環境で使い回せます。コンテナ化の書き方は[Spring BootのDockerfileの書き方](https://www.issoh.co.jp/tech/details/1929/)にまとめています。

### スレッド数・最大接続数・待ち行列の既定値とチューニングの順番

[共通アプリケーションプロパティの一覧](https://docs.spring.io/spring-boot/appendix/application-properties/index.html)（4.1.2）に載っている、性能に効くTomcatのプロパティと既定値は次のとおりです。表のプロパティ名は`server.tomcat.`の後ろの部分だけを書いています。

| プロパティ             | 既定値  | 意味            |
| ----------------- | ---- | ------------- |
| threads.max       | 200  | 処理スレッドの上限     |
| threads.min-spare | 10   | 待機スレッドの下限     |
| max-connections   | 8192 | 同時に受け付ける接続の上限 |
| accept-count      | 100  | 上限到達後のOSの待ち行列 |

このほか、`spring.threads.virtual.enabled`（既定は`false`）で仮想スレッドを使うかを切り替えます。

調整は、まずデータベースの接続プール数と`threads.max`の釣り合いを見るところから始めます。スレッドを増やしてもDB接続が足りなければ、待つ場所が移るだけです。仮想スレッドを有効にすると`threads.max`と`threads.min-spare`は効かなくなると一覧に書かれているので、両方を同時に調整しても意味がありません。

古い記事にある`server.tomcat.max-threads`や`server.tomcat.min-spare-threads`は、現行のプロパティ一覧に載っていない名前です。書き写すと設定が効かないまま本番に出るので、`threads.max`の形に直してください。

### 単体Tomcatから移すと変わるタイムアウト既定値とアクセスログの出力先

単体Tomcatの`server.xml`に慣れた人がつまずきやすいのは、既定値の出どころです。`server.tomcat.connection-timeout`は一覧の既定値欄が空欄で、その場合はTomcatのコネクタ自身の既定値に従います。[HTTPコネクタの設定リファレンス](https://tomcat.apache.org/tomcat-11.0-doc/config/http.html)では`connectionTimeout`の既定値は60000ミリ秒で、配布物に同梱の`server.xml`は20000ミリ秒を設定していると書かれています。単体で20秒だった値が、組み込みでは60秒になりうるということです。

```
# 単体Tomcatの server.xml と同じ値を明示する
server.tomcat.connection-timeout=20s

# アクセスログを残す（既定は無効）
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a %r %s (%D microseconds)
# 既定では一時ディレクトリに出るため、置き場所を固定する
server.tomcat.basedir=/var/lib/myapp/tomcat
```

`server.tomcat.basedir`は未指定だと一時ディレクトリが使われ、アクセスログもその下の`logs`に出ます。ドキュメントでも、推奨されているのはベースディレクトリを固定する設定です。OSの一時ファイル掃除でログが消える事故を避けるため、本番では必ず指定します。

### プロパティで足りない設定をWebServerFactoryCustomizerで書く方法

プロパティに無いコネクタの属性は、Javaで設定します。[サーブレットWebアプリのドキュメント](https://docs.spring.io/spring-boot/reference/web/servlet.html)にある例は、`WebServerFactoryCustomizer`を実装したBeanから`TomcatServletWebServerFactory`に触る形です。

```
import java.time.Duration;

import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyTomcatWebServerFactoryCustomizer
        implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory server) {
        // 非同期リクエストのタイムアウトを20秒にする
        server.addConnectorCustomizers(
            (connector) -> connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis()));
    }
}
```

Spring Boot 4ではパッケージ構成が分かれ、`TomcatServletWebServerFactory`は`org.springframework.boot.tomcat.servlet`パッケージにあります。3.x向けの記事のimport文をそのまま貼るとコンパイルが通らないので、版に合ったドキュメントの例から書き始めてください。

## 組み込みTomcatをJettyへ差し替える手順とUndertowが使えなくなった経緯

### Tomcatスターターの除外とJetty追加によるpom.xmlの切り替え設定

Jettyへの切り替えは、Tomcatのスターターを除外してJettyのスターターを足すだけです。[組み込みWebサーバーのドキュメント](https://docs.spring.io/spring-boot/how-to/webserver.html)に載っている形は次のとおりです。

```
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webmvc</artifactId>
  <exclusions>
    <!-- 組み込みTomcatを外す -->
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<!-- 代わりに Jetty を使う -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
```

切り替えた後は、`server.tomcat.*`で書いていた設定が一切効かなくなります。アクセスログなら`server.jetty.accesslog.*`のように、Jetty側のプロパティへ書き直してください。HTTP/2はTomcatならそのまま使えますが、Jettyでは`jetty-http2-server`などの追加の依存が要ります。**切り替える理由が明確でなければTomcatのままにします。**情報量と運用経験者の数で、Tomcatのほうが困ったときに調べやすいからです。

### Spring Boot 4でUndertowスターターが削除された理由と移行先

[4.0の移行ガイド](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide)は、Spring Boot 4がServlet 6.1を前提とし、Undertowがまだ対応していないため、スターターを含めてUndertowのサポートを外したと説明しています。前の表でも、4.1.2の管理依存から`undertow-core`が消えています。

Undertowで動いている3.5系のアプリは、Spring Boot 4へ上げる前にサーバーを移す必要があります。移行先は、サーバー固有の設定が少ないならTomcat、Jetty固有の機能を使いたい事情があればJettyです。手順としては、3.5系のうちにTomcatへ差し替えて負荷試験を通し、そのあとでSpring Boot 4へ上げると、問題の原因を切り分けやすくなります。Servlet APIのパッケージ名が`javax`のまま残っている古いコードがあれば、先に[javaxからjakartaへの移行手順](https://www.issoh.co.jp/tech/details/19271/)を済ませてください。

## 組み込みTomcatの実行可能jarと外部TomcatへのWARデプロイの選び分け

### 外部Tomcat向けWARの作成手順と起動クラス・依存スコープの設定

外部のTomcatに載せる場合は、[従来型デプロイのドキュメント](https://docs.spring.io/spring-boot/how-to/deployment/traditional-deployment.html)に沿って3か所を変えます。起動クラスで`SpringBootServletInitializer`を継承する、パッケージングを`war`にする、組み込みTomcatの依存を`provided`にする、の3点です。

```
<!-- pom.xml -->
<packaging>war</packaging>

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

// 起動クラス
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
```

Gradleでは`spring-boot-starter-tomcat-runtime`を`providedRuntime`に入れます。`provided`にした組み込みTomcatは`lib-provided`に入るため、できたWARは外部Tomcatにも載り、`java -jar`でも起動します。一方で、WebFluxのアプリはWARデプロイに対応していません。外部Tomcatの系列がアプリの前提とずれると動かないので、4.x系なら外部側も11.0系にそろえます。外部Tomcat自体の構成は[Tomcatとは](https://www.issoh.co.jp/tech/details/18726/)で解説しています。

### 実行可能jarを標準にしてWARを選ぶのは3つの条件に限る判断基準

新しく作るアプリで標準として選ぶ形式は、実行可能jarです。Tomcatの版がアプリのビルド定義で決まるので、版上げがアプリの変更として履歴に残り、テストも通せます。外部Tomcatの版は別の担当がサーバー側で管理することが多く、脆弱性対応のたびに調整が要ります。

WARを選ぶのは、次のどれかに当てはまる場合です。

- 1台の外部Tomcatに複数のアプリを同居させる運用が決まっていて、すぐには変えられない
- JSPで作った画面が残っている（公式ドキュメントは、実行可能jarではJSPが動かないと明記している）
- サーバーの構成管理を別部署が持ち、アプリ側はWARの納品までと契約や規程で決まっている

3つ目は技術ではなく組織の事情ですが、現実には最も多い理由です。その場合でも、WARを`java -jar`で起動できる形のまま作っておけば、将来jarの運用へ移るときの手戻りを減らせます。外部Tomcatで動く既存の業務システムを、組み込みTomcatのjarやコンテナの構成へ作り替えたい場合は、[フルスクラッチ開発](https://www.issoh.co.jp/service/system/fullscratch/)で現状の構成の調査から相談を受けています。

## よくある質問

Spring Bootの組み込みTomcatについて、検索の多い質問に答えます。

### Spring Bootに組み込まれているTomcatのバージョンはどう決まりますか？

Spring Bootの`spring-boot-dependencies`（BOM）が版を決めています。2026年11月3日時点で、Spring Boot 4.1.2が管理する`tomcat-embed-core`の版は11.0.27、3.5.16が管理する版は10.1.55です。版を書かずに依存を宣言すればこの値になるため、通常はSpring Bootを上げると組み込みTomcatも上がります。手元のアプリの実際の版は、Mavenの`dependency:tree`やGradleの`dependencyInsight`で確かめられます。

### 組み込みTomcatのバージョンだけを上げても問題ありませんか？

同じ系列内のパッチ番号を上げる用途なら、公式の手段として`tomcat.version`プロパティが用意されています。ただし公式は、各リリースは特定の版の組み合わせで検証されており、上書きは互換性の問題を招きうると警告しています。`tomcat-embed-core`・`el`・`websocket`の3つを同じ版にそろえ、テストを通してから出してください。Spring Bootの次の修正版が同じ版以上を管理したら上書きは外します。

### application.propertiesでTomcatの最大スレッド数を変えるには？

`server.tomcat.threads.max`で指定します。既定値は200です。待機スレッドの下限は`server.tomcat.threads.min-spare`（既定10）で変えます。古い記事にある`server.tomcat.max-threads`は現行のプロパティ一覧に無い名前なので使わないでください。`spring.threads.virtual.enabled=true`で仮想スレッドを有効にすると、この2つの設定は効かなくなります。

### Spring Boot 4でUndertowは使えますか？

使えません。Spring Boot 4の移行ガイドによると、4系はServlet 6.1を前提としており、Undertowがまだ対応していないため、Undertowのスターターごとサポートが外されました。4.1.2の管理依存にも`undertow-core`はありません。3.5系でUndertowを使っているアプリは、Spring Boot 4へ上げる前に組み込みTomcatかJettyへ差し替える必要があります。

### 組み込みTomcatを使わずに外部のTomcatで動かせますか？

動かせます。起動クラスで`SpringBootServletInitializer`を継承し、パッケージングを`war`にして、`spring-boot-starter-tomcat`を`provided`スコープにします。できたWARは外部Tomcatへの配置に加えて、`java -jar`による起動も可能です。ただしWebFluxのアプリはWARデプロイに対応していません。外部Tomcatの系列は、アプリが前提とするServletの版にそろえてください。

## 関連記事

- [Spring Bootとは｜4.1系の依存名の変更と最小Web APIの作り方](https://www.issoh.co.jp/tech/details/17478/)：組み込みTomcatで動くアプリの作り方の全体像
- [Tomcatのバージョン確認方法｜version.sh・起動ログ・管理画面・Spring Boot組み込み版の調べ方と脆弱性の影響判定](https://www.issoh.co.jp/tech/details/19269/)：本番に載った組み込み版の確かめ方
- [Apache Tomcatの脆弱性一覧【2026年10月】最新版11.0.27・10.1.61・9.0.123とCVE-2026-59083ほかの影響確認・対応手順](https://www.issoh.co.jp/tech/details/15405/)：組み込み版を上げるか判断するための影響範囲
- [Spring Bootバージョン一覧とサポート期限（EOL）【2026年10月】最新版は4.1、4.0の無償サポートは12月末終了](https://www.issoh.co.jp/tech/details/5172/)：組み込みTomcatの版を決めるSpring Bootの系列と期限
- [Tomcatのバージョン一覧とサポート期限【2026年10月】最新版11.0.27、9.0系は2027年3月末終了・9.1系は2030年末まで](https://www.issoh.co.jp/tech/details/18728/)：外部Tomcatで運用する場合の系列の期限

---

出典: [Spring Bootの組み込みTomcat｜tomcat.versionでの版上げ・server.\*設定・Jetty切替・WAR化の手順【4.1.2対応】](<https://www.issoh.co.jp/tech/details/19273/>)（株式会社一創）
