有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

可序列化对象上的java InvalidClassException

我在与同事的代码集成时遇到一些问题

他有一个实体类,我们称之为FooEntity

@Entity
@XmlRootElement
@Table(name = "...")
public class FooEntity implements Serializable {

    private static final long serialVersionUID = ...;
    ...

    @Lob
    @Column(name = "OBJBYTES")
    private Serializable objBytes;

    ...
}

他正在创建他的DTO对象

public class FooDTO implements Serializable {

    private static final long serialVersionUID = ...;

    ...

    private Serializable obj;
    ...
}

通过助手类

public class FooHelper {

    ...

    public static Serializable createSBar() {
        Bar bar = generateBar();
        Serializable sBar = bar;
        return sBar;
    }

    ...

}

创建实现Serializable接口的Bar对象:

public class Bar implements Serializable {

    private static final long serialVersionUID = ...;

    private String myString;
    private byte[] myBytes;
}

在他的DAO中,他从DTO对象创建实体对象并将其保存到数据库中,检索实体对象并将其映射到DTO对象

通过^{}检索与特定条件匹配的条目列表时,会抛出InvalidClassException和以下消息:

Local Exception Stack: 
Exception [EclipseLink-66] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Could not deserialize object from byte array.
Internal Exception: java.io.InvalidClassException: com.my.package.Bar; local class incompatible: stream classdesc serialVersionUID = 4849912519109332230, local class serialVersionUID = -1015090985675288072
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[objBytes-->FOO_TABLE.OBJBYTES]
Descriptor: RelationalDescriptor(com.my.package.entity.FooEntity --> [DatabaseTable(FOO_TABLE)])
    at org.eclipse.persistence.exceptions.DescriptorException.notDeserializable(DescriptorException.java:1218)
    at org.eclipse.persistence.mappings.converters.SerializedObjectConverter.convertDataValueToObjectValue(SerializedObjectConverter.java:72)
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getAttributeValue(AbstractDirectMapping.java:699)
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.valueFromRow(AbstractDirectMapping.java:1299)
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.buildCloneFromRow(AbstractDirectMapping.java:1258)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:1548)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:1694)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:664)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:601)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:560)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:717)
    at org.eclipse.persistence.queries.ReadObjectQuery.registerResultInUnitOfWork(ReadObjectQuery.java:778)
    at org.eclipse.persistence.queries.ReadObjectQuery.executeObjectLevelReadQuery(ReadObjectQuery.java:457)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1081)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
    at org.eclipse.persistence.queries.ReadObjectQuery.execute(ReadObjectQuery.java:418)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1128)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
    at org.eclipse.persistence.internal.indirection.NoIndirectionPolicy.valueFromQuery(NoIndirectionPolicy.java:323)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRowInternal(ForeignReferenceMapping.java:2098)
    at org.eclipse.persistence.mappings.OneToOneMapping.valueFromRowInternal(OneToOneMapping.java:1695)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRow(ForeignReferenceMapping.java:1987)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.buildCloneFromRow(ForeignReferenceMapping.java:276)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:1548)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:1694)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:664)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:601)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:560)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:717)
    at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:769)
    at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:433)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1081)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:392)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1128)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1463)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:485)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:742)
    at com.my.package.dao.FooDAO.getRange(FooDAO.java:584)
    ...
Caused by: java.io.InvalidClassException: com.my.package.Bar; local class incompatible: stream classdesc serialVersionUID = 4849912519109332230, local class serialVersionUID = -1015090985675288072
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:560)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1599)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1494)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1748)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1327)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:349)
    at org.eclipse.persistence.mappings.converters.SerializedObjectConverter.convertDataValueToObjectValue(SerializedObjectConverter.java:70)
    ... 165 more

还需要注意的是,在Glassfish 3.1.2.2中部署应用程序时,日志中会显示以下消息:

[#|2014-06-05T12:39:01.301+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.FooEntity actually got transformed|#]

[#|2014-06-05T12:39:01.310+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo2Entity actually got transformed|#]

[#|2014-06-05T12:39:01.316+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo3Entity actually got transformed|#]

[#|2014-06-05T12:39:01.322+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo4Entity actually got transformed|#]

[#|2014-06-05T12:39:01.327+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo5Entity actually got transformed|#]

[#|2014-06-05T12:39:01.332+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo6Entity actually got transformed|#]

[#|2014-06-05T12:39:01.337+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo7Entity actually got transformed|#]

[#|2014-06-05T12:39:01.345+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo8Entity actually got transformed|#]

有人能解释为什么会发生这种异常以及如何解决它吗? 另外,我假设将实体对象用作JAXB对象不是一个好的实践,对吗


共 (1) 个答案

  1. # 1 楼答案

    如错误消息所示:

    Internal Exception: java.io.InvalidClassException: com.my.package.Bar; local class incompatible: stream classdesc serialVersionUID = 4849912519109332230, local class serialVersionUID = -1015090985675288072

    似乎有两个不同的serialVersionUIDs,这似乎是导致错误的原因。你必须找出为什么会有不同的值,也许值在这段时间内发生了变化