2009年2月10日星期二

Exception loading sessions from persistent storage

今天在Glassfish V3上运行项目时总是时不时地出现以下两个错误(两个错误不同时出现):
错误信息(1)

严重: PWC2773: Exception loading sessions from persistent storage
java.lang.ClassCastException: cannot assign instance of java.lang.String to field cn.beans.UserSession.time of type java.util.Date in instance of cn.beans.UserSession
at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2032)
at java.io.ObjectStreamClass.setObjFieldValues(ObjectStreamClass.java:1212)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1953)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
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.apache.catalina.session.StandardSession.readRemainingObject(StandardSession.java:1835)
at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1767)
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.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
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.apache.catalina.session.StandardSession.deserialize(StandardSession.java:1106)
at org.apache.catalina.session.StandardManager.readSessions(StandardManager.java:513)
at org.apache.catalina.session.StandardManager.doLoadFromFile(StandardManager.java:443)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:413)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:874)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5331)
at com.sun.enterprise.web.WebModule.start(WebModule.java:456)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:922)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:906)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:696)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2205)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1890)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:85)
at com.sun.enterprise.v3.server.ApplicationLifecycle.start(ApplicationLifecycle.java:560)
at com.sun.enterprise.v3.server.ApplicationLifecycle.start(ApplicationLifecycle.java:547)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:189)
at com.sun.enterprise.v3.server.ApplicationLoaderService.processApplication(ApplicationLoaderService.java:260)
at com.sun.enterprise.v3.server.ApplicationLoaderService.postConstruct(ApplicationLoaderService.java:97)
at com.sun.enterprise.v3.server.ApplicationLoaderInjector.postConstruct(ApplicationLoaderInjector.java:61)
at com.sun.hk2.component.AbstractWombImpl.inject(AbstractWombImpl.java:150)
at com.sun.hk2.component.ConstructorWomb$1.run(ConstructorWomb.java:90)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.hk2.component.ConstructorWomb.initialize(ConstructorWomb.java:87)
at com.sun.hk2.component.AbstractWombImpl.get(AbstractWombImpl.java:75)
at com.sun.hk2.component.SingletonInhabitant.get(SingletonInhabitant.java:58)
at com.sun.hk2.component.LazyInhabitant.get(LazyInhabitant.java:107)
at com.sun.hk2.component.AbstractInhabitantImpl.get(AbstractInhabitantImpl.java:60)
at com.sun.enterprise.v3.server.AppServerStartup.run(AppServerStartup.java:203)
at com.sun.enterprise.v3.server.AppServerStartup$1.run(AppServerStartup.java:116)

------------------------------------------------------------------------------------------------------------
错误信息(2)

严重: PWC2768: IOException while loading persisted sessions: java.io.StreamCorruptedException: unexpected end of block data
java.io.StreamCorruptedException: unexpected end of block data
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
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.apache.catalina.session.StandardSession.readRemainingObject(StandardSession.java:1835)
at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1767)
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.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
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.apache.catalina.session.StandardSession.deserialize(StandardSession.java:1106)
at org.apache.catalina.session.StandardManager.readSessions(StandardManager.java:513)
at org.apache.catalina.session.StandardManager.doLoadFromFile(StandardManager.java:443)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:413)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:874)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5331)
at com.sun.enterprise.web.WebModule.start(WebModule.java:456)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:922)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:906)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:696)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2205)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1890)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:85)
at com.sun.enterprise.v3.server.ApplicationLifecycle.start(ApplicationLifecycle.java:560)
at com.sun.enterprise.v3.server.ApplicationLifecycle.start(ApplicationLifecycle.java:547)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:189)
at com.sun.enterprise.v3.server.ApplicationLoaderService.processApplication(ApplicationLoaderService.java:260)
at com.sun.enterprise.v3.server.ApplicationLoaderService.postConstruct(ApplicationLoaderService.java:97)
at com.sun.enterprise.v3.server.ApplicationLoaderInjector.postConstruct(ApplicationLoaderInjector.java:61)
at com.sun.hk2.component.AbstractWombImpl.inject(AbstractWombImpl.java:150)
at com.sun.hk2.component.ConstructorWomb$1.run(ConstructorWomb.java:90)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.hk2.component.ConstructorWomb.initialize(ConstructorWomb.java:87)
at com.sun.hk2.component.AbstractWombImpl.get(AbstractWombImpl.java:75)
at com.sun.hk2.component.SingletonInhabitant.get(SingletonInhabitant.java:58)
at com.sun.hk2.component.LazyInhabitant.get(LazyInhabitant.java:107)
at com.sun.hk2.component.AbstractInhabitantImpl.get(AbstractInhabitantImpl.java:60)
at com.sun.enterprise.v3.server.AppServerStartup.run(AppServerStartup.java:203)
at com.sun.enterprise.v3.server.AppServerStartup$1.run(AppServerStartup.java:116)
严重: PWC2773: Exception loading sessions from persistent storage
java.io.StreamCorruptedException: unexpected end of block data
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
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.apache.catalina.session.StandardSession.readRemainingObject(StandardSession.java:1835)
at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1767)
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.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
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.apache.catalina.session.StandardSession.deserialize(StandardSession.java:1106)
at org.apache.catalina.session.StandardManager.readSessions(StandardManager.java:513)
at org.apache.catalina.session.StandardManager.doLoadFromFile(StandardManager.java:443)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:413)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:874)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5331)
at com.sun.enterprise.web.WebModule.start(WebModule.java:456)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:922)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:906)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:696)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2205)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1890)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:85)
at com.sun.enterprise.v3.server.ApplicationLifecycle.start(ApplicationLifecycle.java:560)
at com.sun.enterprise.v3.server.ApplicationLifecycle.start(ApplicationLifecycle.java:547)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:189)
at com.sun.enterprise.v3.server.ApplicationLoaderService.processApplication(ApplicationLoaderService.java:260)
at com.sun.enterprise.v3.server.ApplicationLoaderService.postConstruct(ApplicationLoaderService.java:97)
at com.sun.enterprise.v3.server.ApplicationLoaderInjector.postConstruct(ApplicationLoaderInjector.java:61)
at com.sun.hk2.component.AbstractWombImpl.inject(AbstractWombImpl.java:150)
at com.sun.hk2.component.ConstructorWomb$1.run(ConstructorWomb.java:90)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.hk2.component.ConstructorWomb.initialize(ConstructorWomb.java:87)
at com.sun.hk2.component.AbstractWombImpl.get(AbstractWombImpl.java:75)
at com.sun.hk2.component.SingletonInhabitant.get(SingletonInhabitant.java:58)
at com.sun.hk2.component.LazyInhabitant.get(LazyInhabitant.java:107)
at com.sun.hk2.component.AbstractInhabitantImpl.get(AbstractInhabitantImpl.java:60)
at com.sun.enterprise.v3.server.AppServerStartup.run(AppServerStartup.java:203)
at com.sun.enterprise.v3.server.AppServerStartup$1.run(AppServerStartup.java:116)

通过观察不难发现,这两个错误都是发生在“loading sessions from persistent storage”之时,也就是从持久化文件还原session的时候。我们都知道Tomcat能够在容器关闭时将session中的数据持久化到文件系统中,待容器重启时将其还原,但前提条件是保存在session中的数据类型均实现了java.io.Serializable接口,glassfish的Servlet容器是基于Tomcat构建的,所以原理基本相同,而且Glassfish是默认开启session持久化的。

于是解决第一个问题的答案就有了:cn.beans.UserSession中的time属性是java.util.Date类型的,而Date没有实现Serializable接口、所以只需创建一个Date的子类令其实现Serializable接口,并将time定义为该子类的对象即可。

而解决第二个问题就需要彻底保证所有保存在session中的数据都是序列化了的才行。当然如果不考虑session持久化就不需要这样做了,只需禁用session持久化功能即可,这一点上tomcat与glassfish略有不同:

1.Tomcat中禁用/启用session持久化:在Tomcat的配置文件server.xml中添加以下内容:

禁用持久化:

<context path="..." reloadable="..." docbase="..." workdir="...">

<manager classname="org.apache.catalina.session.StandardManager">

</manager>

</context>



启用持久化:

<context path="..." reloadable="..." docbase="..." workdir="...">

<manager classname="org.apache.catalina.session.PersistentManager" saveonrestart="true">

</manager>

</context>

2.Glassfish中禁用/启用持久化:Glassfish项目中都有名为sun-web.xml的文件,要禁用session持久化只需在该文件中进行以下配置

<sun-web-app>  
<session-config>
<session-manager>
<manager-properties>
<property name="sessionFilename" value="" />
</manager-properties>
</session-manager>
</session-config>
</sun-web-app>


sessionFilename的值是用来指定一个自定义名称的文件来保存session数据的,而将其设为空值便能够取消session持久化的功能。

参考资料:http://blogs.sun.com/jluehe/entry/how_to_disable_persisting_of

http://my.donews.com/woodstudio/2006/03/05/tomcat-session%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E9%97%AE%E9%A2%98/

http://forums.sun.com/thread.jspa?threadID=575302

没有评论: