[Seasar-user:11909] Re: [Teeda]public transient xxClass xxField;

Yasuo Higa [E-MAIL ADDRESS DELETED]
2007年 12月 5日 (水) 10:21:02 JST


ひがです。
> 
> お世話になります、竹内です。
> 
>   だいぶ中断してしまいまして申し訳ありません。やっと余裕ができ
> サンプルも作成しました。その結果分かったことは以下の条件で再現する
> ことです。
> 
> ■発生の条件
> 1)PageClass の共通の親クラスに パブリックフィールドがあり
>      そこにはSerializableなObjectが入る

Helperのような振る舞いが中心のオブジェクトは、
Serializableにしてデータを持ち運びしないように
したほうがいいと思います。

よろしくお願いします。

> 2)上記のObjectはHelperであり、S2がDIしてくれるもの
> 3)HelperにはCustomizerが設定されておりS2がEnhanceしている
>       参考:cutomizer.dicon に(A)の指定あり
> 4)HotDeployで動作(env.txt が ut)
> 5)同じ親クラスを継承する別のPageに遷移
> 
> メカニズムも考察してみましたが、あっているでしょうか?
> 
> ■発生のメカニズム考察:
>  TeedaがPage遷移の時にパブリックでSerializableなので引き継ぎ対象とする
>  HotDeployのために、当該ObjectをSerializeしてSessionなどに保存
>    Hotの場合は1回ごとにクラス定義などをクリアして最初から
>    ロードするための措置
>  遷移先のPageに同じパブリックフィールドが存在
>  Teedaは当該ObjectをDeserializeして引き渡そうとする
>  当該Objectにクラス定義はS2により動的にEnhanceされたものである
>  Hotの振舞いにより古いクラス定義が破棄されているため復元できずエラー
> 
> 
> ■対策として想定されること
>   HelperなどのEnhanceされる可能性のあるものはSerializable不可とするか、
>   パブリックはやめてSetterだけを作成する形にする
> 
>   EntityやDTOなどもSerializableにしてPageにくっつけた場合に、Customizer
> やAOPの直接指定でEnhanceされた場合に同じ現象が発生するような気がしますが
> どんなもんでしょうか?
> 
> ----- 添付:サンプル -----
> 解凍してteeda-html-example に配置すれば即動作するはずです。
> 最初のページでUID/PSWに同じものを入れてボタンを押すと参考資料
> の(B)のようなExceptionが発生します。
> 
> http://localhost:8080/teeda-html-example/view/pubfld/start1.html
> 
> ----- 参考:(A) ----- customizer.dicon で指定されている helperCutomizer
>   <component name="helperCustomizer" class="org.seasar.framework.container.
customizer.CustomizerChain">
>     <initMethod name="addCustomizer">
>       <arg>traceCustomizer</arg>
>     </initMethod>
>   </component>
> 
> ----- 参考:(B) ----- Exception
> DEBUG 2007-12-05 01:37:13,836 [http-8080-Processor25] [ESSR0044]クラスが
> 見つかりませんでした。詳細はjava.lang.ClassNotFoundException:
> examples.teeda.helper.KwSelectItemHelper$$EnhancedByS2AOP$$7a6e84
> org.seasar.framework.exception.ClassNotFoundRuntimeException: [ESSR0044]クラ
スが見つかりませんでした。詳細はjava.lang.ClassNotFoundException:
 examples.
teeda.helper.KwSelectItemHelper$$EnhancedByS2AOP$$7a6e84
> 	at org.seasar.framework.container.hotdeploy.HotdeployUtil$
RebuilderImpl.rebuild(HotdeployUtil.java:166)
> 	at org.seasar.framework.container.hotdeploy.HotdeployUtil.
rebuildValueInternal(HotdeployUtil.java:126)
> 	at org.seasar.framework.container.hotdeploy.HotdeployUtil.rebuildValue
(HotdeployUtil.java:107)
> 	at org.seasar.framework.container.external.
RebuildableExternalContextMap.get(RebuildableExternalContextMap.
java:59)
> 	at javax.faces.internal.scope.VariableScope.getContexts(VariableScope.
java:100)
> 	at javax.faces.internal.scope.VariableScope.getContext(VariableScope.
java:50)
> 	at javax.faces.internal.scope.SubApplicationScope.getContext
(SubApplicationScope.java:36)
> 	at org.seasar.teeda.extension.html.impl.ScopeValueHelper.
getSubApplicationScopeValues(ScopeValueHelper.java:38)
> 	at org.seasar.teeda.extension.html.impl.SessionPagePersistence.restore
(SessionPagePersistence.java:109)
> 	at org.seasar.teeda.extension.html.impl.HtmlViewHandler.
setUpRequestForExternalBinding(HtmlViewHandler.java:110)
> 	at org.seasar.teeda.extension.html.impl.HtmlViewHandler.restoreView
(HtmlViewHandler.java:103)
> 	at org.seasar.teeda.core.lifecycle.impl.RestoreViewPhase.
composeViewRoot(RestoreViewPhase.java:113)
> 	at org.seasar.teeda.core.lifecycle.impl.RestoreViewPhase.executePhase
(RestoreViewPhase.java:81)
> 	at org.seasar.teeda.core.lifecycle.AbstractPhase.execute(AbstractPhase.
java:57)
> 	at org.seasar.teeda.core.lifecycle.LifecycleImpl.execute(LifecycleImpl.
java:68)
> 	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:94)
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:269)
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:188)
> 	at org.seasar.framework.container.hotdeploy.HotdeployFilter.doFilter
(HotdeployFilter.java:63)
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:215)
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:188)
> 	at org.seasar.framework.container.filter.S2ContainerFilter.doFilter
(S2ContainerFilter.java:64)
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:215)
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:188)
> 	at org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter
(ExtensionsFilter.java:122)
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:215)
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:188)
> 	at org.seasar.extension.filter.EncodingFilter.doFilter(EncodingFilter.
java:69)
> 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:215)
> 	at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:188)
> 	at org.apache.catalina.core.StandardWrapperValve.invoke
(StandardWrapperValve.java:210)
> 	at org.apache.catalina.core.StandardContextValve.invoke
(StandardContextValve.java:174)
> 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.
java:127)
> 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.
java:117)
> 	at org.apache.catalina.core.StandardEngineValve.invoke
(StandardEngineValve.java:108)
> 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.
java:151)
> 	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.
java:870)
> 	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.
processConnection(Http11BaseProtocol.java:665)
> 	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket
(PoolTcpEndpoint.java:528)
> 	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt
(LeaderFollowerWorkerThread.java:81)
> 	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run
(ThreadPool.java:685)
> 	at java.lang.Thread.run(Thread.java:619)
> Caused by: java.lang.ClassNotFoundException: examples.teeda.helper.
KwSelectItemHelper$$EnhancedByS2AOP$$7a6e84
> 	at java.lang.ClassLoader.findClass(ClassLoader.java:358)
> 	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
> 	at org.seasar.framework.container.hotdeploy.HotdeployClassLoader.
loadClass(HotdeployClassLoader.java:71)
> 	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
> 	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
> 	at java.lang.Class.forName0(Native Method)
> 	at java.lang.Class.forName(Class.java:247)
> 	at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:604)
> 	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:
1575)
> 	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
> 	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:
1732)
> 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
> 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
> 	at java.util.HashMap.readObject(HashMap.java:1030)
> 	at sun.reflect.GeneratedMethodAccessor118.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:
974)
> 	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:
1846)
> 	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:
1753)
> 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
> 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
> 	at java.util.HashMap.readObject(HashMap.java:1030)
> 	at sun.reflect.GeneratedMethodAccessor118.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:
974)
> 	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:
1846)
> 	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:
1753)
> 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
> 	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:
1945)
> 	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:
1869)
> 	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:
1753)
> 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
> 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
> 	at java.util.HashMap.readObject(HashMap.java:1030)
> 	at sun.reflect.GeneratedMethodAccessor118.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:
974)
> 	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:
1846)
> 	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:
1753)
> 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
> 	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:
1945)
> 	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:
1869)
> 	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:
1753)
> 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
> 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
> 	at org.seasar.framework.container.hotdeploy.HotdeployUtil$
RebuilderImpl.rebuild(HotdeployUtil.java:162)
> 	... 41 more
> 
> 
> 
> On Wed, 17 Oct 2007 15:00:04 +0900
> Koichi Kobayashi <[E-MAIL ADDRESS DELETED]> wrote:
> 
> > 小林 (koichik) です.
> > 
> > Date:    Wed, 17 Oct 2007 10:57:01 +0900
> > From:    "TAKEUCHI Shinichi / 竹内 伸一" <[E-MAIL ADDRESS DELETED]>
> > To:      [E-MAIL ADDRESS DELETED]
> > Subject: [Seasar-user:11052] Re: [Teeda]public transient xxClass xxField;
> > 
> > >   public 宣言していたのはPageクラスの共通の親となるAbstractクラス
> > > でして、TakeOver宣言はしていませんでした。
> > 
> > そうでしたか.
> > 
> > > 親クラスでのPublicは
> > > 自動的に引継ぎの対象となってしまうということでしょうか?
> > 
> > そんなことはないです.
> > 
> > >   また、引継がない場合は、Desirialize時にS2コンテナが再度
> > > DIしてくれるということですね。
> > 
> > ちょっと違います.
> > Page クラス自体はシリアライズ・デシリアライズの
> > 対象ではなく,そのプロパティ (public field 含む) が
> > 対象です.
> > ただし,Serializable でないプロパティは対象外です.
> > # プロパティに設定されているオブジェクトではなく
> > # プロパティの型で判断しているので,KSelectItemHelper が
> > # インタフェースの場合はこの KSelectItemHelper が
> > # Serializable を extends していないと対象になって
> > # しまいます.
> > 
> > Page クラスはリクエストの度に新しいインスタンスが
> > コンテナから取得されます.
> > Helper などはその際に DI されます.
> > なので,Page クラスは Serializable にする必要は
> > ありません.
> > # もし Serializable にしているなら外してください.
> > 
> > ひとまず,
> > 
> > [Seasar-user:11011]
> > >   HotDeployで実行しているのですが、単にpublic宣言だけですと、
> > > ページを遷移する時にNotSerializableExceptionが発生します。そこで、
> > 
> > この時のスタックトレースも見せてください.
> > # transient が無いケースです.
> > # 上の数行ではなく,丸ごと全部お願いします.
> > 
> > できれば,現可能な最低限のサンプルを提供して
> > いただくのがいいと思います.
> > その際は Teeda HTML Example に置くだけで
> > 確認できるようだと助かります.
> > 
> > 
> > -- 
> > <component name="koichik">
> >     <property name="fullName">"Koichi Kobayashi"</property>
> >     <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
> >     <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
> > </component>
> > 
> > _______________________________________________
> > Seasar-user mailing list
> > [E-MAIL ADDRESS DELETED]
> > https://ml.seasar.org/mailman/listinfo/seasar-user
> > 
> 
> -- 
> TAKEUCHI Shinichi / 竹内 伸一 <[E-MAIL ADDRESS DELETED]>
> 
> 
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
> 
> 
> 
> 


Seasar-user メーリングリストの案内