【问题标题】:NotSerializableException when shutting down glassfish关闭 glassfish 时出现 NotSerializableException
【发布时间】:2012-01-29 23:08:41
【问题描述】:

由于HtmlSelectOneMenu,我在关闭 Glassfish (3.1) 时收到了 NotSerializableException。我在其他控制器 bean 中使用HtmlSelectOneMenu,但它们并没有像这个那样绑定到支持 bean。当然,只有在服务器上存在活动会话时才会发生这种情况。

在为有界 JSF 组件启动/停止 Glassfish 时如何避免异常?

控制器类

@ManagedBean
@SessionScoped
...

public class ActivityController implements Serializable {
    ..
    private DataModel<MyObjcet> items = null;
    private HtmlSelectOneMenu myMenu;
    ...

例外

INFO: PWC2785: Cannot serialize session attribute activityController for session a4591e053e65effc743dade67eef
java.io.NotSerializableException: javax.faces.component.html.HtmlSelectOneMenu
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
    at org.apache.catalina.session.StandardSession.writeObject(StandardSession.java:2067)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
    at org.apache.catalina.session.StandardManager.writeSessions(StandardManager.java:699)
    at org.apache.catalina.session.StandardManager.doUnloadToFile(StandardManager.java:618)
    at org.apache.catalina.session.StandardManager.unload(StandardManager.java:589)
    at org.apache.catalina.session.StandardManager.stop(StandardManager.java:879)
    at org.apache.catalina.core.StandardContext.stop(StandardContext.java:5509)
    at com.sun.enterprise.web.WebModule.stop(WebModule.java:529)
    at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:1049)
    at com.sun.enterprise.web.WebContainer.unloadWebModule(WebContainer.java:2191)
    at com.sun.enterprise.web.WebContainer.unloadWebModule(WebContainer.java:2146)
    at com.sun.enterprise.web.WebApplication.stop(WebApplication.java:151)
    at org.glassfish.internal.data.EngineRef.stop(EngineRef.java:169)
    at org.glassfish.internal.data.ModuleInfo.stop(ModuleInfo.java:302)
    at org.glassfish.internal.data.ApplicationInfo.stop(ApplicationInfo.java:314)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.unload(ApplicationLifecycle.java:997)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.disable(ApplicationLifecycle.java:1952)
    at com.sun.enterprise.v3.server.ApplicationLoaderService.stopApplication(ApplicationLoaderService.java:443)
    at com.sun.enterprise.v3.server.ApplicationLoaderService.preDestroy(ApplicationLoaderService.java:411)
    at com.sun.hk2.component.AbstractCreatorInhabitantImpl.dispose(AbstractCreatorInhabitantImpl.java:83)
    at com.sun.hk2.component.SingletonInhabitant.release(SingletonInhabitant.java:81)
    at com.sun.hk2.component.EventPublishingInhabitant.release(EventPublishingInhabitant.java:108)
    at com.sun.hk2.component.LazyInhabitant.release(LazyInhabitant.java:133)
    at com.sun.enterprise.v3.server.AppServerStartup.stop(AppServerStartup.java:415)
    at com.sun.enterprise.glassfish.bootstrap.GlassFishImpl.stop(GlassFishImpl.java:88)
    at com.sun.enterprise.v3.admin.StopServer.doExecute(StopServer.java:70)
    at com.sun.enterprise.v3.admin.StopDomainCommand.execute(StopDomainCommand.java:95)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.run(CommandRunnerImpl.java:383)

【问题讨论】:

    标签: jsf-2 glassfish java-ee-6


    【解决方案1】:

    设为transient

    private transient HtmlSelectOneMenu myMenu;
    

    这样,在(反)序列化时将跳过该字段。顺便说一句,DataModel 也是不可序列化的。

    另一方面,在大多数情况下,将组件直接绑定到 backing bean 是一种气味。您应该考虑寻找(或询问)不需要将组件绑定到 bean 的替代方法。

    【讨论】:

    • 我为我得到异常的类(包括 HtmlSelectOneMenu 和 DataModel)声明了它们是瞬态的。但是我还有其他几个具有非瞬态 DataModel 的 Controller 类(会话范围),我对此也不例外。怎么可能?
    • 它在序列化期间显然没有价值(即它是null)。也许整个字段都未使用,因此可以安全地删除。
    • 没错,它们可能还没有填充数据。谢谢,新年快乐!
    猜你喜欢
    • 2014-09-02
    • 2014-11-05
    • 2013-10-26
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多