1

JSFベースのJavaWebアプリケーションで次の例外が発生し続けており、それについてのグーグルは、アプリケーションスコープのjsfマネージドBeanがシリアル化可能であることが原因である可能性があることを示唆しています。

 java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.apache.catalina.session.StandardSessionFacade
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1509)
    at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:998)
    at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:394)
    at org.apache.catalina.session.StandardManager.load(StandardManager.java:321)
    at org.apache.catalina.session.StandardManager.start(StandardManager.java:648)
    at org.apache.catalina.core.ContainerBase.setManager(ContainerBase.java:446)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4631)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:675)
    at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:601)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:502)
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1317)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1065)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
    at org.apache.catalina.core.StandardService.start(StandardService.java:525)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: java.io.NotSerializableException: org.apache.catalina.session.StandardSessionFacade
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at org.apache.catalina.session.StandardSession.writeObject(StandardSession.java:1585)
    at org.apache.catalina.session.StandardSession.writeObjectData(StandardSession.java:1015)
    at org.apache.catalina.session.StandardManager.doUnload(StandardManager.java:528)
    at org.apache.catalina.session.StandardManager.unload(StandardManager.java:469)
    at org.apache.catalina.session.StandardManager.stop(StandardManager.java:678)
    at org.apache.catalina.core.StandardContext.stop(StandardContext.java:4882)
    at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:936)
    at org.apache.catalina.startup.HostConfig.undeployApps(HostConfig.java:1359)
    at org.apache.catalina.startup.HostConfig.stop(HostConfig.java:1330)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:326)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
    at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1098)
    at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1110)
    at org.apache.catalina.core.StandardEngine.stop(StandardEngine.java:468)
    at org.apache.catalina.core.StandardService.stop(StandardService.java:604)
    at org.apache.catalina.core.StandardServer.stop(StandardServer.java:788)
    at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:408)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.stopServer(Bootstrap.java:338)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:416)

問題のマネージドBeanは、@ ManagedPropertyアノテーションを使用して、セッションスコープのBeanに注入される場合があります。

これは悪い習慣ですか、それとも私が得られない何か他のものですか?

4

3 に答える 3

0

うーん...私の理解では、@ApplicationScopedマネージドBeanは、アプリケーションがデプロイされている限り存続します。つまり、必要なときにBeanを保存して復元する必要はないと思います。常にそこにあるはずです。

@ApplicationScopedBeanをBeanとして注入する代わりに、@ManagedPropertyBeanをBeanに注入してから、そのBeanをBeanに@SessionScoped注入してみませんか。:)@RequestScoped@RequestScoped@SessionScoped

于 2012-06-22T08:50:11.970 に答える
0

これは、JSF マネージド Bean 機能が Java シリアライゼーションと統合されていないためです。aBean が anotherBean に依存している場合、anotherBean のインスタンスが aBean に注入されます。オブジェクトをシリアライズするとそのフィールドもシリアライズされるため、anotherBean も同様にシリアライズされます。これはせいぜいメモリの浪費であり、最悪の場合は実装が非常に困難です (シリアライズできない依存関係がある可能性があるため...)。

CDI や Spring などの適切な依存性注入コンテナは、現在の anotherBean に委譲するシリアライズ可能なプロキシを aBean に注入することで、この問題を解決します。これが、バッキング Bean を別の DI コンテナーに保持する必要がある理由の 1 つです。(JSF で CDI または Spring 管理の Bean を使用するのは非常に簡単です)。

編集: Java EE 5 でロックされていることに同情します。この場合、次のようにすることができます。

  1. アプリケーション スコープの Bean への参照を依存関係として保持するのではなく、必要なときに名前で検索します。
  2. アプリケーション スコープの Bean のシリアライズ可能なプロキシを挿入します (または、アプリケーション スコープの Bean 自体をシリアライズ可能にします)。これには、シリアライゼーション メカニズムにフックして Bean を名前でシリアライズし、ルックアップによるデシリアライズ時に再構築する必要があります。
  3. Bean を 2 つに分割します。1 つのオブジェクトは依存関係 (リクエスト スコープ) 用、もう 1 つのオブジェクトは状態 (セッション スコープ) 用です。個人的には、バッキング Bean の意味のあるカプセル化には、これが面倒で法外なことだと思いますが、それは好みの問題です。
于 2012-06-22T12:08:45.230 に答える
0

org.apache.catalina.session.StandardSessionFacadeTomcat の の実装ですHttpSession。したがって、この例外は、ビュー/セッション スコープのマネージド Bean の 1 つに次のプロパティがあることを示唆しています。

private HttpSession session;

これは完全に間違っています。そんなことは絶対にしてはいけません。FacesContextExternalContextおよびそのすべてのアーティファクトにも同じ話が当てはまります。これらはマネージド Bean のプロパティとして宣言するべきではありませんが、常にスレッド ローカル スコープ (つまり、それらが必要な場所とまったく同じメソッド ブロック内) で宣言する必要があります。

于 2013-05-20T13:43:46.980 に答える