Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

tomcat5.5の Session について

最近の事なのですがtomcatを4系から5.5へとアップグレードいたしました。

そこでいろいろな問題が頻発し、なかなか解決に至らないのでちょっと質問させていただきます。(色々といってもこの場ではセッションのことのみの質問とさせていただきます)

質問内容は単純です。
セッションオブジェクトにArrayList型のオブジェクトが格納できないということです。

状況といたしましては4系で使っていたアプリケーションをそのままディレクトリごとtomcat5.5のwebapps以下にコピーしたものを使用しております。

サーブレットにおいてArrayList型のオブジェクトをセッションオブジェクトへ格納しフォワード先のJSPにおいてそのオブジェクトを取り出し処理をするというものです。がそのフォワード先のJSPでNullPointerExsampleのエラーが発生します。

以上の点を踏まえて-------
1■4系のtomcatでは同じコードのものがなんら問題なく動いております。
2■「repuest.getAttribute()」などは正常に扱える。
3■logなど(cataline.outやlocalhost_*.log)などには一切の出力はなし。(NullPointerExsampleはブラウザ上のスタックトレース)
4■そもそもsession.setAttribute()後のセッションNull判定を行うとNullという結果に陥っている。
-------などの問題がでています。

tomcat4系とtomcat5.5ではセッションのセッションの取り扱いに関して何らかの仕様の変更はあったのでしょうか?この辺をご教授いただければと思います。

ちなみに以前ここで質問させていただいたコネクションプーリングなどの問題は解決いたしました。

ではよろしくお願いします。


12

回答

5901

閲覧

12件の回答

評価

0

>NullPointerExsample
こんなエラーはないんですが。
質問をするのなら、きちんと調べて正確に書きましょう。

なんでしょうね。私はとくに、気にした覚えがないんですが…。
しかもArrayListだけなんでしょうか?

評価

0

1.セッションに入れる時のキーがちゃんと合っているか?
2.セッションIDが同一か?

上記を調べてみては?

評価

0

質問の回答ではありませんが、もしかするとカネダさんの役に立つ部分があるかもしれませんので、Tomcat4と5.5の間の設定における違いを分かる範囲ですが示しますね。

・Servlet・JSPの仕様が2.3/1.2から2.4/2.0になった。
・Tomcat5.5はJavaのバージョンが1.5.0以上でなければ動かない
・Tomcat4ではクラスをロードする際の順番が/WEB-INF/classes
  /WEB-INF/lib の方がブートストラップクラスやクラスパスより先に
  検索されたが、5.0以降ではブートストラップクラス、クラスパス
  の方が先に検索される。
・Tomcat4ではserver.xmlのHost要素にネストしたContext要素で
  行っていたウェブアプリケーションの設定は5.0以降では
  コンテキストルート(WEB-INFのあるディレクトリ)に
  META-INFディレクトリを作成してその中にcontext.xmlとして設定する。
  (XML宣言に続きserver.xmlのContext要素切り出してコピーした内容になる)
・Tomcat4ではContext要素におけるデータソースの設定をResourceと
  ResourceParams要素で行っていたが5.5ではパラメータはResourceの
  属性として設定する。

評価

0

返事にだいぶ遅れてすいません。。。
ここ数日かなり忙しかったので・・・

まず、
>質問をするのなら、きちんと調べて正確に書きましょう
すいませんこの質問を書いていたときかなり急いでいたもので記憶を頼りに適当に書いてしまいました。

>しかもArrayListだけなんでしょうか?
ArrayListだけではありませんでした。それ以外に問題がありました。あとに書きます。

>1.セッションに入れる時のキーがちゃんと合っているか?
これは問題ありませんでした。何しろ同じアプリケーションがtomcat4のほうではサクサク動いています。

>2.セッションIDが同一か?
そうです問題はここでした。アクセスする(リロード押す)たびにセッションIDが変化していました。
要するにセッションにオブジェクトを保持できなかったのではなくてセッションからオブジェクトを取り出す際に中身のないセッションオブジェクト取り出そうとしてNullPointerExceptionのエラーが出ます。

さあ問題はここからです。
なんでセッションIDが変化するのでしょうか?
ソース的には
  HttpSession session = request.getSession(true);
  System.out.println("SessionID = " + session);
みたいなことをやっています。

tomcat4のほうでは同じブラウザからアクセスする限りきっちり同じIDが取得されています。
このほかにログなどに出力されるものはありません。
ちなみにHttpSessionクラスのソースコードをわざわざ見てみたのですがただのインターフェースでして・・・実際にどこのクラスで処理の実装をされているのかわかりませんでした。。。

解決の糸口がありません。
なにかヒント的なことでもありませんでしょうか。。。
よろしくお願いします。。。

たぶん、どうせserver.xmlかweb.xmlあたりに原因があると思いますが・・・・。

評価

0

ブラウザにcookieは吐かれてますか?

評価

0

>ブラウザにcookieは吐かれてますか?
cookieは正常に動作しているようです。
sessionに関しても同じくフォワード先のJSPでsession.getId()で同じIDを取得できているようです。ということはブラウザ側の設定やその他の環境の問題でないという事はなんとなく想像できます。

要するに問題は
  HttpSession session = request.getSession(true);
の位置にあると思います。

上記のコードなら普通、ユーザがsessionIDを保持していたなら新しいsessionを生成せず既存のsessionIDを使う用になっているはずですが、私のtomcat5.5では必ず新しいsessionIDを生成してしまいます。
ちなみに引数をfalseにするとnullが返ってしまいます。

HttpServletRequestクラスのgetSession()メソッドに問題があるのか?
もしくは受ける側のHttpSessionクラスのほうに問題があるのか?
どちらかだと思っていますが、「どちらか?」といううまい切り分け方法が思いつきません。

もしかしたらtomcatの仕様の変更などでsession情報の保持をしないような設定に知らない間になっているのかも知れませんが今のところ僕の調べた限りではそのようなことは確認できていません。。。

評価

0

context.xmlに<Manager>要素は追加していますか?
あとクラスタリング機能を有効化してみるのもいいかも。
何らかのヒントが出てくるかもしれません。

評価

0

5.5のリビジョンはいくつですか。最新にしたら直ったりしませんか。

評価

0

皆さん回答ありがとうございます。

>context.xmlに<Manager>要素は追加していますか?
これは追加していません。なんとなくややこしくてまだそちらの方に余裕が向きません。Session系のパラメータを定義する要素というのは分かっているのですが・・・

>あとクラスタリング機能を有効化してみるのもいいかも。
クラスタリング機能は有効化していますがSessionIDが毎回変わってしまているので動作を確認するという所までいけません。

>5.5のリビジョンはいくつですか。最新にしたら直ったりしませんか。
バージョンはapache-tomcat-5.5.20です。これは今現在最新のものと認識しております。
ちなみに余談ですが色々調べてると(googleでtomcat5.5などで検索すると)たまにjakarta-tomcat-5.5.9とか見るけど「apache-tomcat-」と「jakarta-tomcat」は何が違うんでしょうかね?

ちょっとtomcatを4系から5.5に変えて色々問題が発生して参ってます。
自分の環境の問題もあるかと思いますが「ナンデ?」と思うようなことばかりです。
(アプリケーション自体はtomcat4系で問題なく動いていたのとまったく同じアプリケーションを配備しています)
■まずパフォーマンスが異常に悪い。
tomcatを職場の自分の専用のサーバで色々動作確認をしているのですが休日の次の日に覗いてみると何もしていないのに必ずtomcatがDownしている。
しかも他のアプリケーション(特にSSHとpostfix)も道連れにしています。なぜかApacheはDownしていない・・・

■プロセスやネットワーク系のステータスが4系で動かしている時とまったく違う。
特にデータベースコネクション系のステータス。4系のアプリケーションをそのまま持ってきて動かしてみたらESTABLISHED(接続中)、データベースプロセスのidol状態がどんどん無限に増えていき、とうとうブラウザにページを表示できないという状況に陥っていた。tomcatはDownしていない。(これはコードを少し改良することによって改善しましたが、これはjavaによるwebアプリケーションの基本的な理念に反しているような気がする)

■で、一番の問題はこのスレッドでも質問しているSessionの問題です。
上の二つにかんしては別に動いている間にプログラムのテストなどを実施できますが、この問題に関しては解決しないと特に使いたい機能=クラスタリング機能などを試せないという状況になります。

よくtomcat5.5の環境を使用して質問をしている人を見かけますがこのような問題は起こってないのでしょうか?

評価

0

うーん…。

>■プロセスやネットワーク系のステータスが4系で動かしている時とまったく違う。
これはちと分かりませんが、パフォーマンスの問題はとくに感じませんね。

リコンパイルして配備しなおしてみては…。

ところでJDKはいくつですか。
私のところだと、JDK1.5→1.6で、けっこうパフォーマンスが改善されました。
1.6はまだ実績がないので、業務で使うのはどうかとも思いますが、いちおう。

評価

0

皆さんご無沙汰しております。
とうとうこのスレッドにケリをつける時がやってきました。

やっぱりこうゆうワケの分からない問題が起こる原因は単純なミスが原因なようです。

まぁナイとは思いますが、
今後こういう同じ問題が発生した人のため、
このスレッドにケリをつけるという責任を果たすため、
恥を忍んで回答いたします。

結論から申します。
「使うライブラリを間違っていた」というのが答えです。

まずtomcat4ではサーブレットに使われるライブラリは「servlet.jar」ですが、tomcat5.5では「servlet-api.jar」に変わっています。
もちろんtomcat5.5をインストールした時点で適切な場所にこのライブラリはキッチリと含まれております。
ではなぜこのようなミスが起こったのかということです。

まず、tomcatを4から5.5へ上げたのと同時にjavaのバージョンも1.4から1.5へ上げました。
その際、当然、環境変数を書き換えます。クラスパスも当然書き換えます。が、これをディレクトリ部分だけしか書き変えなかったのです。要するに「/usr/local/tomcat4/common/lib/servlet.jarから/usr/local/tomcat5/common/lib/servlet.jarにです」で、「いざ、最新の1.5でコンパイルだ!」ということで実行すると、通りません。
これは当然です。tomcat5.5のcommon/lib/には「servlet.jar」というライブラリなんて含まれていないからです。(実際含まれているのは「servlet-api.jar」です。パスを通すのも「servlet.jar」でなく「servlet-api.jar」にしなければならなかった。)もちろんコンパイルエラーでHttpServletクラスはなんちゃら、かんちゃらと出て来ます。
「あれっ!」と思い、なんでライブラリがないというようなエラーが出るのかなと思った時、悪魔の手段がフッと頭をよぎったのです。色々考えた結果、

「めんどくさいからtomcat4のcommon/lib/からライブラリを全部コピーしちゃえばなんとかなるだろ!」

という手段にでてしまいました。
間違いはこれでした。もちろんtomcat5.5のcommon/lib/下には「servlet.jar」というライブラリがセットされます。コンパイルも通ります。
すると不思議なことに「servlet.jar」でコンパイルされたアプリケーションはtomcat5.5上ではなぜかSessionIDがうまくセットできないとい現象が発生してしまうのです。

と、まあ結論はこんなところです。

mioさんの
>リコンパイルして配備しなおしてみては…。
>ところでJDKはいくつですか。
でなんとなくフッと気づきました。

mioさんワケの分からない質問であったにもかかわらずヒントを与え続けてくれたことへ感謝します。
そのほかにも色々アドバイスをくれた方々にもお礼を申し上げます。

では、さようなら。

評価

0

なるほど…。
言われてみれば、私も、同僚がそのライブラリを間違えていて、うまく動かないというのがありました。
セッションではなかったように思いますが。

ま、正直なところ、いきなりライブラリ名を変えるほうも問題な気はしますけどね。
リリースノートに書いてあったような気もしますが。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。