Jakarta Servlet徹底解説:仕様・移行・実践ベストプラクティス

はじめに

Jakarta Servlet(以下・Jakarta Servlet)は、サーブレットAPIの最新体系であり、従来のJava EE(javax.servlet.*)からEclipse Foundationの Jakarta EE プラットフォームへ移行した後の名称とパッケージ(jakarta.servlet.*)を指します。Webアプリケーションの基盤として長年使われてきた仕様で、サーブレットコンテナ(Tomcat、Jetty、Undertow など)上で動作するHTTP処理の基本となります。本稿では仕様の歴史、コア概念、移行時の注意点、実運用で役立つ知見を深掘りして解説します。

Jakarta Servletとは何か

サーブレットはサーバーサイドでHTTPリクエストを処理するためのJavaインタフェース群とライフサイクルの定義です。Jakarta Servletはその仕様の現在のブランド名で、主に次を提供します。

  • HTTPリクエスト/レスポンスを操作するAPI(jakarta.servlet.http.HttpServletRequest/Response)
  • リクエスト処理ライフサイクル(init→service→destroy)
  • フィルタやリスナといったクロスカッティング機能
  • 非同期処理・マルチパート処理・ノンブロッキングIOなどの拡張

大きな転換点は Jakarta EE 9 でのパッケージ名変更です。従来の javax.servlet.* が jakarta.servlet.* に置き換わり、これに伴い関連するライブラリ・Webアプリケーション・デプロイ記述子(web.xml の名前空間)も更新が必要となりました。

主なバージョンと歴史的な変更点(概要)

  • Servlet 3.0(Java EE 6 相当): アノテーションベースの構成(@WebServlet、@WebFilter、@WebListener)、非同期処理(AsyncContext)、ファイルアップロードのサポート(multipart)などを導入。
  • Servlet 3.1(Java EE 7 相当): ノンブロッキングIO(ReadListener/WriteListener)を導入し、高スループットのI/O処理を可能にした。
  • Servlet 4.0(Java EE 8 相当): HTTP/2のサポートを仕様に取り込み、HTTP/2の利点(多重化、ヘッダ圧縮、サーバープッシュ等)を利用可能にした。
  • Jakarta Servlet 5.0(Jakarta EE 9): 大きな機能追加というよりも、最大の変更点はパッケージの javax.* → jakarta.* へのリネーム。既存コード・バイナリは移行が必要。
  • Jakarta Servlet 6.0(Jakarta EE 10 以降): 仕様の進化やマイナーな拡張が行われています(詳細は各仕様書参照)。

サーブレットの基本概念とライフサイクル

サーブレットは基本的に javax.servlet.Servlet(現 jakarta.servlet.Servlet)インタフェースを実装します。最も使われるのは HttpServlet で、doGet/doPost などのメソッドをオーバーライドして処理します。ライフサイクルは大きく3段階です。

  • init(ServletConfig): コンテナによる初期化。リソースの確保や設定読み込みを行う。
  • service(HttpServletRequest, HttpServletResponse): リクエストごとの処理。内部で doGet/doPost などに振り分けられる。
  • destroy(): コンテナ終了時やアンロード時に呼ばれ、リソース解放を行う。

同時にフィルタ(Filter)やリスナ(ServletContextListener など)を使って、認証・ロギング・トランザクション境界などの横断的関心事を管理します。

主要なAPIと実務で多用する機能

  • 非同期処理(AsyncContext): 長時間処理をスレッドプールへオフロードし、スレッドの占有を避ける。非同期処理はスケーラビリティ向上に有効。
  • ノンブロッキングIO(Servlet 3.1 の ReadListener/WriteListener): 大量同時接続を効率的に処理するために利用。
  • Multipartサポート: ファイルアップロードを標準でサポート。@MultipartConfigや HttpServletRequest#getParts を利用。
  • Dispatch(forward/include)とエラーページ: リクエストディスパッチで MVC 構成の一部を扱う。
  • セッション管理: HttpSession を使った簡易的なセッション管理だが、分散環境では外部ストア(Redis等)やセッションレプリケーションを検討。
  • セキュリティ: web.xml の security-constraint / programmatic login など。近年はフレームワーク(Spring Security 等)で補完されることが多い。

javax.* から jakarta.* への移行(実務上の注意点)

Jakarta EE 9 の最大の変化はパッケージ名の変更です。これに伴い、単純に依存JARを切り替えるだけでは済まない点が多く存在します。実務上の具体的な対応は以下の通りです。

  • ソースとバイナリの変換: import 文を jakarta.servlet.* に変更する必要がある。既存のライブラリやサードパーティ依存が javax.* を前提とする場合、両者を混在させることはできない。
  • web.xml の名前空間: web.xml のスキーマURI/namespace も jakarta のものに変更する必要がある(例: "https://jakarta.ee/xml/ns/jakartaee" など)。
  • コンテナの選定: Tomcat、Jetty 等でも jakarta 対応バージョンを選ぶ。例えば Tomcat 9 は Servlet 4.0(javax.*)に対応、Tomcat 10 系は jakarta.* をサポートしている(詳細はコンテナのドキュメント参照)。
  • 移行ツール: ソース/バイトコードの自動変換には Eclipse Transformer や Tomcat の移行ツールなどが利用できる。これらを使うことでワーニングや手作業を減らせる。
  • テストの重要性: 変換後は統合テスト・機能テストを徹底し、ランタイムの互換性問題(クラスローダや誤ったライブラリの混在)を検出する。

移行のための実践的ワークフロー(例)

  • 現状分析: 使用しているサードパーティライブラリで javax.* を使用しているものを洗い出す。
  • 依存関係の更新: 可能であれば jakarta 対応版のライブラリに差し替える。
  • ツールで変換: Eclipse Transformer や Tomcat Migration Tool を使ってバイナリ/ソースを変換。
  • コンテナ切替: jakarta に対応したコンテナ上でデプロイして検証(ステージング環境で入念に確認)。
  • 回帰テスト・性能テスト: 機能面だけでなく性能面での影響も計測。非同期やノンブロッキングAPIを使っている場合は特に注意。

パフォーマンスと運用のベストプラクティス

  • スレッド管理の徹底: Servletはスレッドに敏感。インスタンス変数に状態を持たせる場合はスレッドセーフに設計するか、明示的にスコープを限定する。
  • 非同期処理を活用: ブロッキングIOや長時間処理は AsyncContext に移行してスレッドの枯渇を防ぐ。
  • ノンブロッキングIOの検討: 大量の同時接続(WebSocketやストリーミング)を扱うなら ReadListener/WriteListener の採用を検討。
  • 接続・セッション管理: セッションの肥大化やCookieの使い方に注意。分散環境ではセッションストアの外部化を行う。
  • ライフサイクルフックの利用: ServletContextListener 等でリソースの初期化・クリーンアップを明確に管理。
  • セキュリティ更新の適用: コンテナや依存ライブラリの脆弱性は速やかにパッチを適用する。

よくあるトラブルと対処法

  • クラスキャスト例外やNoClassDefFoundError: javax と jakarta の混在が主因。依存関係を精査して片方に統一する。
  • web.xml のスキーマ違いでのデプロイ失敗: web.xml の namespace を jakarta 用に更新する。
  • サードパーティが jakarta 未対応: アップデートが無い場合は自前で変換ツールを走らせるか、互換レイヤー/プロキシを用いる。

まとめ

Jakarta Servlet は長年のサーブレット仕様の蓄積を受け継ぎつつ、Jakarta EE への移行によってパッケージ命名の変更という大きな転換点を迎えました。機能面(非同期、ノンブロッキング、HTTP/2 等)は既存の知見がそのまま活きますが、移行にあたってはライブラリの互換性やデプロイ記述子の名前空間など細部に注意が必要です。移行ツールやコンテナの対応状況を確認し、ステージングで十分な検証を行うことが成功の鍵となります。

参考文献