[Wicket-ja-user 528] Re: Tomcat のセッション復元後の、ブラウザからのアクセスについて

Back to archive index

Michiaki Kanou michi****@gmail*****
2011年 4月 30日 (土) 01:54:23 JST


お世話になります。加納と申します。

Wicket1.3.6でお問い合わせの手順に従った再現テストを行ってみたんですが、
手順どおりのやり方ではうまく再現できませんでした。

ただし、以下の条件を加えると、お問い合わせにあるNullPointerException
がスローされることを確認しました。

条件1)対象のWebページがステートフルであること。
条件2) WebApplicationクラスのinternalDestroy()をオーバーライドしている。
       ただし、super.internalDestroy()は実装しない。

Tomcatの停止と開始が条件になっていることから、なんとなくセッションシリアライズの
保存と読み込みになんらかの不整合が起きているのではないかと
思われたんですが、 WebApplicationクラスのinternalDestroy()を
オーバーライドするような実装をしてませんでしょうか?

あと、Tomcatの停止の仕方によっても再現したり、しなかったりすることも
あるようでして、

Tomcatのシャットダウンコマンドで終了した場合は再現しましたが、
killコマンドで終了させるような場合では再現しないようです。


2011年4月26日14:34 Masaya seko <masay****@nifty*****>:
> お世話になっております。世古と申します。
> あるWicketの事象について、以下の前提で回避する方法は無いか考えております。
> ・使用するWicketのバージョンを上げない。
> ・Wicketの独自ビルドを作らない。
>  (即ち、アプリ側で解決したい)
>
> 一応案はあるのですが、以下について意見を伺いたいと思ってメールを書いております
>> ・何かもっと良い方法
> ・この案のまずい点があれば、まずい点
>
>
> ■環境
> ・Tomcat 5.5.33
> ・Wicket 1.3.6
> ・IE6
>
>
> ■回避したい事象
> 以下の流れで発生します。
> 「ERROR」という形でログが記録されるためこれについて回避したいと考えています。
> 1.WebApplication#init()内で以下のコードを実行し、RequestLoggerを有効にします
>>   getRequestLoggerSettings().setRequestLoggerEnabled(true);
> 2.aタグに、hover時の画像をbackgroundで設定しておきます。
>   (ロールオーバー時に画像を読み込んでしまうIEのバグ(?)をあえて踏むため。参考
>http://www.webbibo.com/blog/htmlcss/bg_flickr.html)
>   画像は、スタイルの定義されているCSSをwicket:linkで囲むなどし、Wicket経由で
> 配信されるようにします。
> 3.そのタグが存在するページをIEで表示します。
> 4.IEのキャッシュから、画像を消します。
> 5.Tomcatを停止します。
> 6.Tomcatを開始します。
> 7.aタグにマウスカーソルをあてます。
>   (IEのバグ(?)により、画像をサーバから取得しようとします。)
> 8.ログに以下のメッセージが記録されます。
>   ERROR RequestLogger - Exception while determining the size of the session
> in the request logger: null
>   (本当はスタックトレース込みでもっと長いメッセージが記録されるのですが、長
> いため後述)
>
>
> ■判明していること
> 根本原因は、以下のバグと同一のようです。
> Wicket1.3.xの実装に一箇所nullチェックが抜けておりまして、そのために例外が発生
> します。
> https://issues.apache.org/jira/browse/WICKET-2099
>
> 私にとって困ったことに、WICKET-2099のバグは1.3.x系では修正されていません。
> (1.4.x系では修正されているのですが…)
>
>
> ■対応案
> 本当は、DiskPageStore#prepareForSerialization(String, Object)を綺麗にオーバー
> ライドしたいのですが、DiskPageStore#prepareForSerialization(String, Object)の
> 実装では、パッケージプライベートなクラスが用いられているため、綺麗にオーバーラ
> イドするのは困難です。
>
> その点を踏まえて、以下のような形で無理やりオーバーライドしようと考えています。
> 簡単に言いますと、NullPointerExceptionを無理やりつぶします。
> □アプリ固有のApplicationクラス
> protected ISessionStore newSessionStore(){
>    return new SecondLevelCacheSessionStore(this, new DiskPageStore() {
>        public Serializable prepareForSerialization(String sessionId, Object p
> age) {
>            try {
>                return super.prepareForSerialization(sessionId, page);
>            } catch (NullPointerException npe) {
>                return null;
>            }
>        }
>    });
> }
>
>
> ■現時点で分かっている対応案のイマイチなところ
> ・RequestLoggerが記録するセッションサイズが、実際よりも(多分)小さくなる。
> ・アドホックな実装であるため、「あるパターンのときに、別の箇所で何か例外が発生
> する」という可能性を否定しきれない。
>  (テストした感じでは、安定的に動作しているのですが…)
>
>
> ■ログに記録されるメッセージの全文
> 2011-04-26 13:18:39,812 ERROR RequestLogger - Exception while determining the
> size of the session in the request logger: null
> java.lang.NullPointerException
>    at org.apache.wicket.protocol.http.pagestore.DiskPageStore.prepareForSeria
> lization(DiskPageStore.java:1163)
>    at org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLeve
> lCachePageMap.writeObject(SecondLevelCacheSessionStore.java:382)
>    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.ja
> va:39)
>    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccesso
> rImpl.java:25)
>    at java.lang.reflect.Method.invoke(Method.java:592)
>    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:917)
>    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1339
> )
>    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:
> 1290)
>    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
>    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:302)
>    at org.apache.wicket.util.lang.Objects$SerializingObjectSizeOfStrategy.siz
> eOf(Objects.java:89)
>    at org.apache.wicket.util.lang.Objects.sizeof(Objects.java:1161)
>    at org.apache.wicket.PageMap.getSizeInBytes(PageMap.java:177)
>    at org.apache.wicket.Session.getSizeInBytes(Session.java:816)
>    at org.apache.wicket.protocol.http.RequestLogger.requestTime(RequestLogger
> .java:232)
>    at org.apache.wicket.RequestCycle.detach(RequestCycle.java:1175)
>    at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1418)
>    at org.apache.wicket.RequestCycle.request(RequestCycle.java:529)
>    at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:35
> 6)
>    at org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:
> 124)
>    at javax.servlet.http.HttpServlet.service(HttpServlet.java:627)
>    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
>    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applic
> ationFilterChain.java:269)
>    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFil
> terChain.java:188)
>    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperVal
> ve.java:213)
>    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextVal
> ve.java:172)
>    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.jav
> a:127)
>    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.jav
> a:117)
>    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve
> .java:108)
>    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
> 174)
>    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:8
> 79)
>    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.pro
> cessConnection(Http11BaseProtocol.java:665)
>    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoin
> t.java:528)
>    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollo
> werWorkerThread.java:81)
>    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPoo
> l.java:689)
>    at java.lang.Thread.run(Thread.java:595)
>
>
> 以上、なにかお分かりになる方が居られましたら、よろしくおねがいします。
>
> _______________________________________________
> Wicket-ja-user mailing list
> Wicke****@lists*****
> http://lists.sourceforge.jp/mailman/listinfo/wicket-ja-user
>




Wicket-ja-user メーリングリストの案内
Back to archive index