サーブレットやJSPの“バージョン”意識してますか?:現場にキく、Webシステムの問題解決ノウハウ(7)
本連載は、日立製作所が提供するアプリケーションサーバ「Cosminexus」の開発担当者へのインタビューを通じて、Webシステムにおける、さまざまな問題/トラブルの解決に効くノウハウや注意点を紹介していく。現在起きている問題の解決や、今後の開発のご参考に(編集部)
10年で「J2EE 1.2」から「Java EE 6」へ
1999年にJ2EE 1.2がリリースされてから10年以上経過し、2009年12月には4回目のバージョンアップ版であるJava EE 6がリリースされた(参考:米Sun、軽量、モジュラー化を進めた「Java EE 6」を公開)。
この間、多くの技術が実装され、またエンハンスされてきたが、エンハンスに伴って以前のバージョンと振る舞いが変わってしまったケースが少なからず存在する。
サーブレット/JSPは、J2EE 1.2リリース当初から存在する歴史と実績のある技術だ。Java EEを適用するほとんどのシステムで利用されている。歴史がある分、多数の機能追加が行われてきたのと同時に、若干だが仕様の変更も行われている。さらに、あいまいだった仕様が明確にされたがために、アプリケーションサーバによっては、振る舞いが変わってしまったものもある。
今回は、振る舞いの変更に起因するトラブル事例と、その回避策を紹介しよう。
【事例1】サーブレットリスナの振る舞い
サーブレットリスナを使うと、サーブレットの開始や終了、セッションの作成や破棄などのイベントに応じて処理できる。
Servlet 2.4では、リスナの延長で実行されているコードで例外が発生した場合の仕様が明確にされた。リスナの延長で実行されているコードで例外が発生すると、エラーページに遷移するか、エラーページが定義されていなければ、クライアントにステータス「500」を返し、かつそのイベントに応じたリスナが複数あったとしても、リスナの呼び出しは打ち切られることが明記された。
一方、Servlet 2.3では、リスナの延長で例外が発生したときの仕様は未定義であり、実装依存だった。
よって、1つのイベントに対して複数のリスナが定義されていると、バージョンによっては動きに差異が生じる可能性がある。つまり、Servlet 2.3に準じて実装されているコンテナは、リスナで例外が発生しても、エラーページに遷移せず、かつ複数のリスナをすべて実行するかもしれないのだ。
複数リスナをすべて実行することを前提としてアプリケーションを実装していると、Servlet 2.4仕様のコンテナ上では期待通りの動作をしなくなってしまう。
【事例2】JSPのpageEncoding属性による文字化け
JSP 2.0の仕様では国際化が強く意識され、JSP 1.2における国際化のあいまいな仕様が明確にされた。その1つにpageディレクティブのpageEncoding属性の有効範囲がある。JSP 2.0の仕様では、pageEncoding属性の適用範囲は、その属性が記述されたファイルだけであること、includeディレクティブでincludeするファイルには適用されないことが明記された。
よって、JSP 2.0に準じたコンテナを使った場合、includeするファイルにpageEncoding属性の指定がなく、かつ日本語を使った場合(に限らないが、ISO-8859-1で表現できない文字が含まれている場合)には、文字化けが発生する。
JSP 1.2では、includeするファイルのpageEncodingについての規定がないため、コンテナによっては、include元のファイルのpageEncodingを引き継ぎ、文字化けが発生しない。
この動きに依存したJSPアプリケーションは、JSP 2.0の仕様のコンテナにアップグレードした途端に文字化けに悩むことになるだろう。
JSP/サーブレットの文字化けに関する対策については、下記記事を参考にしてほしい。
Javaの文字化け対策FAQ
JSP/サーブレット・プログラミングで誰もが一度は遭遇するトラブルが文字化けだ。4回の連載で文字化け解消のポイントを解説する
Java TIPS
Javaプログラミングに役立つテクニックとノウハウ集
・サーブレット2.3における文字エンコーディングの指定
・サーブレット2.2における文字エンコーディングの指定
・文字コード宣言をフィルタで共有化する
・リソースファイルの内容が文字化けする場合には
・リソースファイルで他国語対応サイトを構築する
最新仕様のコンテナにアップグレードするには
最新仕様のコンテナにアップグレードしたいが、「実績あるアプリケーションを変更したくない」「アプリケーションが大きすぎで、アップグレードに伴う検証をする時間がない」という場合も多いことだろう。
例えばCosminexusのアプリケーションサーバでは、web.xmlのスキーマ定義によって、「どのバージョンの挙動をするか」決定しているため、最新仕様のコンテナにアップグレードするときでも、旧バージョンで実績のあるアプリケーションは一切、直す必要がないという。
DTD/XMLスキーマ | バージョン |
---|---|
http://java.sun.com/j2ee/dtds/web-app_2_2.dtd | 2.2 |
http://java.sun.com/dtd/web-app_2_3.dtd | 2.3 |
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd | 2.4 |
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd | 2.5 |
表 DTD/XMLスキーマとWebアプリケーションバージョンの対応 |
どのスキーマを指定しても最新仕様の動きになるアプリケーションサーバも存在する一方、Cosminexusは旧バージョンからの移行性を重視しているようだ。
スキーマ定義と期待するバージョンが一致しない場合
スキーマ定義によらず、最新仕様の動きになるアプリケーションサーバ上でアプリ開発すると、スキーマ定義のバージョンと、アプリケーションが期待するバージョンが一致していない場合がある。例えば、スキーマでは2.3を指定しているにもかかわらず、2.4から採用されたJSP属性を利用している場合などがある。
このようなアプリケーションに対応するためには、「アプリケーションサーバの機能に頼る」のも、1つの手段だ。
例えばCosminexusの場合は、web.xml以外の手段でアプリケーションのバージョンを指定できるという。webserver.application.lower_versionプロパティをユーザープロパティファイルに指定すると、web.xmlに指定されたバージョンを無視し、指定したバージョンの挙動になるそうだ。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- Java TIPS
- JSP/サーブレット編
- 意外と知らないバージョン表記・数字の豆知識
- 第1回 Webアプリの問題点を「見える化」する7つ道具
- 第2回 “Stop the World”を防ぐコンカレントGCとは?
- 第3回 【実録ドキュメント】そのログ本当に必要ですか?
- 第4回 DBアクセスのトラブルは終盤で発覚しがち……
- 第5回 OutOfMemoryエラー発生!? GCがあるのに、なぜ?
- 第6回 【真夏の夜のミステリー】Tomcatを殺したのは誰だ?
- 第7回 【トラブル大捜査線】失われたコネクションを追え!
- 第8回 肥え続けるTomcatと胃を痛めるトラブルハッカー
- 第9回 JavaのGC頻度に惑わされた年末年始の苦いメモリ
- 第10回 ThreadとHashMapに潜む無限回廊は実に面白い?
- 第11回 スレッドダンプの森で覚えた死のロックへの違和感
- 第12回 アプリ開発でも、よ?く考えよう。キャッシュは大事だよ
- 第13回 DB操作の“壁”を壊すJPAが起こした「赤壁の戦い」
- 第14回 数百キロのコードでブルー - ドクターTomcat緊急救命
- 第1回 クラスタ化すると遅くなる?
- 第2回 キャッシュが性能劣化をもたらす謎を解く
- 第3回 クラスタは何台までOK?
- 第4回 マルチスレッドのいたずらに注意
- 第5回 クラスタによるアプリケーションの動的アップデート
- 第6回 APサーバからの応答がなくなった、なぜ?
- 第7回 低負荷なのにCPU使用率が100%?
- 第8回 文字化け“???”の法則とその防止策
- 第9回 メモリは足りているのに“OutOfMemory”のなぞ
- 第10回 レスポンスキャッシュでパフォーマンス向上
- 第11回 JDBC接続を高速化?PreparedCacheの活用
- 第12回 ブラウザキャッシュでパフォーマンス向上
- 第13回 ファイルアップロード/ダウンロードに潜むわな