2011-08-01 54 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

相關問題