本連載は、日立製作所が提供するアプリケーションサーバ「Cosminexus」の開発担当者へのインタビューを通じて、Webシステムにおける、さまざまな問題/トラブルの解決に効くノウハウや注意点を紹介していく。現在起きている問題の解決や、今後の開発のご参考に(編集部)
1999年にJ2EE 1.2がリリースされてから10年以上経過し、2009年12月には4回目のバージョンアップ版であるJava EE 6がリリースされた(参考:米Sun、軽量、モジュラー化を進めた「Java EE 6」を公開)。
この間、多くの技術が実装され、またエンハンスされてきたが、エンハンスに伴って以前のバージョンと振る舞いが変わってしまったケースが少なからず存在する。
サーブレット/JSPは、J2EE 1.2リリース当初から存在する歴史と実績のある技術だ。Java EEを適用するほとんどのシステムで利用されている。歴史がある分、多数の機能追加が行われてきたのと同時に、若干だが仕様の変更も行われている。さらに、あいまいだった仕様が明確にされたがために、アプリケーションサーバによっては、振る舞いが変わってしまったものもある。
今回は、振る舞いの変更に起因するトラブル事例と、その回避策を紹介しよう。
サーブレットリスナを使うと、サーブレットの開始や終了、セッションの作成や破棄などのイベントに応じて処理できる。
Servlet 2.4では、リスナの延長で実行されているコードで例外が発生した場合の仕様が明確にされた。リスナの延長で実行されているコードで例外が発生すると、エラーページに遷移するか、エラーページが定義されていなければ、クライアントにステータス「500」を返し、かつそのイベントに応じたリスナが複数あったとしても、リスナの呼び出しは打ち切られることが明記された。
一方、Servlet 2.3では、リスナの延長で例外が発生したときの仕様は未定義であり、実装依存だった。
よって、1つのイベントに対して複数のリスナが定義されていると、バージョンによっては動きに差異が生じる可能性がある。つまり、Servlet 2.3に準じて実装されているコンテナは、リスナで例外が発生しても、エラーページに遷移せず、かつ複数のリスナをすべて実行するかもしれないのだ。
複数リスナをすべて実行することを前提としてアプリケーションを実装していると、Servlet 2.4仕様のコンテナ上では期待通りの動作をしなくなってしまう。
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.