2011-08-01 3 views
21

My DAO 구현은 Tomcat7을 사용하여 서버를 시작할 때 serializable 예외를 던지고 있습니다. 이게 무슨 일 이니? 내 다른 DAO 중 누구도이 작업을 수행하지 않습니다.Tomcat 7에서 NotSerializableException이 발생하는 이유는 무엇입니까?

다음
<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> 

내 스택입니다 : 여기

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; 
    } 
} 

내 설정 : 그것은 직렬화하는 경우

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

UserDaoImpljava.io.Serializable 인터페이스를 구현해야합니다 (여기

는 클래스의 스택 추적은 인스턴스를 작성하려고 시도했음을 나타냅니다. 객체 스트림에 대한 클래스).

직렬화 할 인스턴스와 해당 인스턴스의 객체 그래프에있는 모든 객체는 모두 직렬화 가능해야합니다. 직렬화위한 JavaDoc을 가입일

, 클래스

직렬화가 를 java.io.Serializable 인터페이스를 구현하는 클래스가 활성화 된 그래프를 가로 지르는 때 ... 객체 는 않는다고 발견 될 수있다 Serializable 인터페이스를 지원하지 않습니다. 이 경우 NotSerializableException이 발생하고 은 serialize 할 수없는 객체의 클래스를 식별합니다.

이러한 규칙에는 예외가 있습니다. 객체 직렬화가 발생하는시기와 NotSerializableException을 피하기 위해 필요한 사항을 완전히 이해하려면 Java Object Serialization Specification을 읽어 보는 것이 좋습니다.

+9

이것은 특별히 유용한 정보는 아닙니다. OP는 * 왜 이것이 시작시에 일어나는 지 알 필요가 있습니다. 직렬화 기법에 대한 상세한 설명이 필요합니다. – skaffman

+1

근위 원인 일 수 있지만 근본 원인은 아닙니다. 어떻게 HibernateTemplate을 직렬화 가능하게 만들 것을 제안합니까? – pap

+1

스프링 관리 빈을 직렬화하는 것은 좋지 않습니다. –

32

코드 어딘가에 세션에 UserDAO를 저장하고 있거나 UserDAO에 대한 참조가있는 개체를 저장하고 있기 때문에 상황이 발생합니다. Tomcat은 모든 활성 세션의 전체 객체 그래프를 종료 할 때 직렬화하려고 시도한 다음 백업을 시작할 때이를 복원하려고 시도합니다. 요점은 Tomcat이 모든 객체가 Serializable 인 "일반적인"Java 객체 직렬화를 사용한다는 것입니다.

를 해결하는 방법 :
  1. 는 사용자 세션 (일반적으로 좋은 연습)에 직렬화 객체를 저장하지 마십시오.
  2. UserDAO를 직렬화 가능하게 만듭니다. 아마도 Serializable 인터페이스를 구현하고 hibernateTemplate을 transient으로 마킹하는 것은 아마 HibernateTemplate이 그 자체로 직렬화 가능하다고 생각하지 않기 때문일 것입니다. desiialization에 hibernateTemplate을 다시 초기화하는 코드를 추가해야 할 수도 있습니다.
  3. Tomcat 직렬화 세션이 없습니다 (<Manager pathname="" />을 자신의 응용 프로그램이나 conf/디렉토리의 globcat.xml에있는 context.xml에 <Context> 요소 안에 추가하십시오.) 액션을 다시 시작할 때마다 유지해야하는 경우가 아니면
+1

나는 이것을 말할 필요가있다. 당신의 대답은 훌륭합니다. 고마워. 고마워. – me1111

13

다른 답변은 직렬화를 잘 설명하기 때문에 Google에서 처음으로 문제가 해결되었으므로 문제를 해결하는 데 도움이되는 정보를 추가하고 싶습니다.

예외 메시지 자체는이 문제를 일으킨 클래스 필드를 나타내지 않습니다. 클래스를 직렬화 할 수 없으며 transient 키워드를 추가해야 Java가 필드 직렬화를 시도하지 않으므로 어떤 필드가 문제를 일으키는 지 파악하는 것이 어려울 수 있습니다.

시작시 Java/Tomcat에 -Dsun.io.serialization.extendedDebugInfo=true 매개 변수를 추가하면 예외가 훨씬 유용합니다. 여기에 예외 메시지가 어떻게 보이는지의 예입니다

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", za.[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

관련 문제