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

"TAKEUCHI Shinichi / 竹 "TAKEUCHI Shinichi / 竹
2007年 12月 5日 (水) 02:02:19 JST


お世話になります、竹内です。

  だいぶ中断してしまいまして申し訳ありません。やっと余裕ができ
サンプルも作成しました。その結果分かったことは以下の条件で再現する
ことです。

■発生の条件
1)PageClass の共通の親クラスに パブリックフィールドがあり
     そこにはSerializableなObjectが入る
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]>
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: pubfld.zip
型:         application/x-zip-compressed
サイズ:     3519 バイト
説明:       無し
URL:        http://ml.seasar.org/archives/seasar-user/attachments/20071205/5e50de16/attachment-0001.bin 


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