2011-08-01 56 views
21

我的DAO实现抛出一个不可序列化的异常,服务器启动Tomcat7。任何想法是什么导致这个?我的其他DAO都没有这样做。在Tomcat 7中导致NotSerializableException的原因是什么?

这里的类:

package com.project.dao; 

import java.util.List; 

import org.hibernate.SessionFactory; 
import org.springframework.orm.hibernate3.HibernateTemplate; 

import com.project.model.User; 

public class UserDAOImpl implements UserDAO { 
    private HibernateTemplate hibernateTemplate; 

    public void setSessionFactory(SessionFactory sessionFactory) { 
     this.hibernateTemplate = new HibernateTemplate(sessionFactory); 
    } 

    @Override 
    public void saveUser(User user) { 
     hibernateTemplate.saveOrUpdate(user); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public List<User> listUser() { 
     return hibernateTemplate.find("from User"); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public User getUserByID(long userID) { 
     List<User> users= hibernateTemplate.find("from User where id = '" + userID + "'"); 
     return users.size() > 0 ? users.get(0) : null; 
    } 
} 

这里是我的配置:

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.0.xsd 
     http://www.springframework.org/schema/mvc 
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 
    <bean id="myDataSource" 
    class="org.apache.tomcat.dbcp.dbcp.BasicDataSource"> 
     <property name="driverClassName"> 
     <value>com.mysql.jdbc.Driver</value> 
     </property> 
     <property name="url"> 
     <value>jdbc:mysql://localhost/context</value> 
     </property> 
     <property name="username"> 
     <value>someUser</value> 
     </property> 
     <property name="password"> 
     <value>somePassword</value> 
     </property> 
     <!-- Disable the second-level cache --> 
     <!-- Echo all executed SQL to stdout --> 
    </bean> 
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
     <property name="dataSource" ref="myDataSource" /> 
     <property name="annotatedClasses"> 
      <list> 
       <value>com.project.model.User</value> 
      </list> 
     </property> 
     <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
      <prop key="hibernate.show_sql">true</prop> 
      <prop key="hibernate.show_sql">true</prop> 
     </props> 
     </property> 
    </bean> 
    <bean id="myUserDAO" class="com.project.dao.UserDAOImpl"> 
     <property name="sessionFactory" ref="sessionFactory"/> 
    </bean> 
</beans> 

这里是我的筹码:

SEVERE: IOException while loading persisted sessions: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: com.news.dao.UserDAOImpl 
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: com.project.dao.UserDAOImpl 

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1332) 
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) 
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) 
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) 
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) 
at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1600) 
at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:1073) 
at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:284) 
at org.apache.catalina.session.StandardManager.load(StandardManager.java:204) 
at org.apache.catalina.session.StandardManager.startInternal(StandardManager.java:470) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5241) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033) 
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:774) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033) 
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:291) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:727) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.startup.Catalina.start(Catalina.java:620) 
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 org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:303) 
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:431) 

Caused by: java.io.NotSerializableException: com.project.dao.UserDAOImpl 
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.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.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:1676) 
at org.apache.catalina.session.StandardSession.writeObjectData(StandardSession.java:1090) 
at org.apache.catalina.session.StandardManager.doUnload(StandardManager.java:411) 
at org.apache.catalina.session.StandardManager.unload(StandardManager.java:353) 
at org.apache.catalina.session.StandardManager.stopInternal(StandardManager.java:497) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.StandardContext$4.run(StandardContext.java:5464) 
at java.lang.Thread.run(Thread.java:662) 
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5481) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:1072) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:1072) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.StandardService.stopInternal(StandardService.java:502) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.StandardServer.stopInternal(StandardServer.java:748) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.startup.Catalina.stop(Catalina.java:693) 
at org.apache.catalina.startup.Catalina.start(Catalina.java:654) 
... 6 more 
Jul 31, 2011 9:27:21 PM org.apache.catalina.session.StandardManager startInternal 

SEVERE: Exception loading sessions from persistent storage 
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: com.project.dao.UserDAOImpl 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1332) 
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) 
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) 
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) 
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) 
at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1600) 
at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:1073) 
at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:284) 
at org.apache.catalina.session.StandardManager.load(StandardManager.java:204) 
at org.apache.catalina.session.StandardManager.startInternal(StandardManager.java:470) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5241) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033) 
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:774) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033) 
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:291) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:727) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) 
at org.apache.catalina.startup.Catalina.start(Catalina.java:620) 
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 org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:303) 
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:431) 

Caused by: java.io.NotSerializableException: com.project.dao.UserDAOImpl 
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.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.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:1676) 
at org.apache.catalina.session.StandardSession.writeObjectData(StandardSession.java:1090) 
at org.apache.catalina.session.StandardManager.doUnload(StandardManager.java:411) 
at org.apache.catalina.session.StandardManager.unload(StandardManager.java:353) 
at org.apache.catalina.session.StandardManager.stopInternal(StandardManager.java:497) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.StandardContext$4.run(StandardContext.java:5464) 
at java.lang.Thread.run(Thread.java:662) 
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5481) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:1072) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:1072) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.StandardService.stopInternal(StandardService.java:502) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.core.StandardServer.stopInternal(StandardServer.java:748) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225) 
at org.apache.catalina.startup.Catalina.stop(Catalina.java:693) 
at org.apache.catalina.startup.Catalina.start(Catalina.java:654) 
... 6 more 
+0

您是将此对象设置在会话中的某个位置还是作为存储在会话中的对象的变量? –

+0

它是存储在会话中的对象中的变量。 – coder

+0

然后删除它,因为这个对象有权访问Hibernate会话,所以它永远不能序列化它自己。 –

回答

21

UserDaoImpl必须实现java.io.Serializable接口,如果它是被序列化(你的堆栈跟踪表明试图编写一个实例该类到一个对象流)。

要序列化的实例以及该实例的对象图中的所有对象都必须是可序列化的。

从的Javadoc序列化,

串行性的一类是通过实现 java.io.Serializable接口类...启用遍历时的曲线图,对象 可以遇到,做不支持Serializable接口。 在这种情况下,将抛出NotSerializableException异常并将 标识不可序列化对象的类。

请注意,这些规则也有例外。我建议您阅读Java Object Serialization Specification以全面了解对象序列化何时发生以及它如何避免NotSerializableException。

+9

这不是特别有用的信息。 OP需要知道*为什么这在启动过程中发生,而不是关于序列化机制的细节。 – skaffman

+1

这可能是最近的原因,但不是根本原因。你打算如何建立一个HibernateTemplate序列化? – pap

+1

序列化spring管理的bean并不是一个好主意。 –

32

发生这种情况是因为代码中的某处,您在会话中存储了一个UserDAO(或者您正在存储具有对UserDAO的引用的对象)。 Tomcat尝试将所有活动会话的完整对象图形序列化,然后在开始备份时尝试恢复它们。关键在于Tomcat使用“正常”的java对象序列化,它要求所有对象都是Serializable

如何补救:

  1. 不要存放在用户会话(通常是一个很好的做法)非序列化对象。
  2. 使您的UserDAO可序列化。可能涉及到实现Serializable接口并将hibernateTemplate标记为transient,因为我不认为HibernateTemplate本身就是可序列化的。如果你真的希望它能够工作,你可能需要添加一些代码来重新初始化反序列化的hibernateTemplate。
  3. 没有Tomcat序列化会话(将<Manager pathname="" />添加到context.xml中,无论是在您自己的应用程序中,还是在conf /目录中的<Context>元素内部的全局tomcat context.xml中。除非你真的需要在重新启动后坚持会话
+1

我需要说这个。你的答案很好。帮助了我很多,谢谢。 – me1111

13

这里的其他答案很好地解释了序列化因为这是Google的第一个结果,我想添加一些真正帮助我解决问题的信息。

异常消息本身并不指示哪个类引起此问题。如果你不能创建一个可序列化的类,并且需要添加transient关键字,以便Java不尝试序列化一个字段,那么确定哪个字段导致问题可能非常棘手。

如果在启动它时将参数-Dsun.io.serialization.extendedDebugInfo=true添加到Java/Tomcat,该异常将更有用。下面是异常消息将是什么样子的例子:

java.io.NotSerializableException: za.co.abc.presentation.control.Three 
- field (class "za.co.abc.presentation.control.Two", name: "three", type: "class za.co.abc.presentation.control.Three") 
- object (class "za.co.abc.presentation.control.Two", [email protected]) 
- field (class "za.co.abc.presentation.control.One", name: "two", type: "class za.co.abc.presentation.control.Two") 
- object (class "za.co.abc.presentation.control.One", [email protected]) 
- field (class "za.co.abc.presentation.control.Trail", name: "one", type: "class za.co.abc.presentation.control.One") 
- root object (class "za.co.abc.presentation.control.Trail", {/click-tests/home.htm=home}) 

如果使用临时关键字,使田不序列,你可能必须再设置这些字段在读类。你必须实现readObject()方法。以下是一个示例:

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { 
    // magically read all non-transient fields from input stream and populate their values 
    in.defaultReadObject(); 

    someTransientField = new NotSerializableClass(); 
} 
+4

用于'-Dsun.io.serialization.extendedDebugInfo = true'的+1,即使对于独立Java应用程序也非常有用。 – javashlook

相关问题