Masaya seko
masay****@nifty*****
2011年 4月 26日 (火) 14:34:34 JST
お世話になっております。世古と申します。 ある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) 以上、なにかお分かりになる方が居られましたら、よろしくおねがいします。