我们在基于JSF的Java Web应用程序中不断获得followng异常,并且谷歌搜索它表明它可能是由应用程序范围的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)
在某些情况下,使用@ManagedProperty批注将有问题的托管bean注入到会话范围的bean中。
这是一种不好的做法,还是我没有得到的其他东西?
答案 0 :(得分:0)
嗯...根据我的理解,只要应用程序已部署,@ApplicationScoped
托管bean就会存在。换句话说,我认为您不需要在需要时存储和恢复bean。应该永远在那里。
不是将@ApplicationScoped
bean作为@ManagedProperty
bean的@SessionScoped
注入,而是为什么不尝试将它注入@RequestScoped
bean然后注入{ {1}} bean进入你的@RequestScoped
bean。 :)
答案 1 :(得分:0)
那是因为JSF托管bean工具没有与Java序列化集成。如果aBean依赖于anotherBean,则将anotherBean的实例注入aBean。由于序列化对象也会对其字段进行序列化,因此anotherBean也将被序列化,这最多是浪费内存,最糟糕的是很难实现(因为它可能具有不可序列化的依赖性......)。
一个体面的依赖注入容器,如CDI或Spring,可以通过将一个可序列化的代理注册到当前的anotherBean到aBean来解决这个问题。这就是为什么人们应该在不同的DI容器中保留豆子的原因之一。 (在JSF中使用CDI或Spring管理的bean非常容易。)
编辑:我对在Java EE 5中被锁定表示同情。在这种情况下,您可能会:
答案 2 :(得分:0)
org.apache.catalina.session.StandardSessionFacade
是Tomcat对HttpSession
的实现。因此,此异常表明您在一个视图/会话范围的托管bean中具有以下属性:
private HttpSession session;
这是完全错误的。你永远不应该这样做。相同的故事适用于FacesContext
,ExternalContext
及其所有工件。永远不应将它们声明为托管bean的属性,但始终在线程局部范围内声明(即在您需要它们的方法块内)。