0

这个套接字将继续接收一些旧对象和同名的新对象。但是,如果我直接使用 readObject,它会抛出致命异常。我们中的一些人会建议忽略旧对象或更改旧对象代码。我无法更改客户端代码。我需要处理 向后兼容性


Socket s = ss.accept();
ObjectInputStream lvStream = new ObjectInputStream(s.getInputStream());
Object lvObject = lvStream.readObject();

// The old class but released ( I cannot change it )
public class Apple extends HashMap<String, String> {
    private static final long serialVersionUID = 1L;
}
// The old class but released ( I cannot change it )
public class Apple extends HashMap<String, String> {
    private static final long serialVersionUID = 2L;
}

// The new class in my local ( 1L or 2L still would not solve the issue easily )
public class Apple extends HashMap<String, String> {
    private static final long serialVersionUID = 2L;
}

在 readObject() 行,我得到了这个致命的异常:

java.io.InvalidClassException 本地类不兼容:流 classdesc serialVersionUID = 1,本地类 serialVersionUID = 2

我如何读取这两种 Apple 对象数据(Hashmap)?

谢谢你。

4

2 回答 2

0

Java:如何readObject()读取两个不同的类serialVersionUID

容易地。他们是不同的班级。为什么不应该呢?

有两个同名但serialVersionUID不同的类。

所以它们是不同的类。你的问题?

我得到了这个致命的例外:

java.io.InvalidClassException local class incompatible : stream classdesc serialVersionUID = 2, local class serialVersionUID = 1

这与不同包中具有相同名称的两个类没有任何关系。这意味着您在发送者处部署了该类的一个版本,在接收者处部署serialVersionUID = 2了不同的版本。serialVersionUID = 1解决方案:不要那样做。部署相同的版本:在这种情况下,带有2, 的版本就是流中的版本。一般来说,您不应该在不确切知道自己在做什么的情况下更改serialVersionUID值。

就我而言,有两个版本的课程发送到我身边。1L 和 2L。

不,没有。有一个版本发送,2L,和不同的版本接收,1L。不要那样做。

于 2016-12-05T09:20:16.007 回答
0

只要我们扩展 ObjectInputStream,

我们将可以访问流 SerialVersionUID 以与本地 SerialVersionUID 进行比较。


Socket s = ss.accept();
// use the extended ObjectInputStream ( DecompressibleInputStream )
DecompressibleInputStreamlvStream = new DecompressibleInputStream(s.getInputStream());
Object lvObject = lvStream.readObject();

import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;

public class DecompressibleInputStream extends ObjectInputStream {

    public DecompressibleInputStream(InputStream in) throws IOException {
        super(in);
    }

    protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
        ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
        Class<?> localClass;
        try {
            localClass = Class.forName(resultClassDescriptor.getName()); 
        } catch (ClassNotFoundException e) {
            System.err.println("No local class for " + resultClassDescriptor.getName());
            return resultClassDescriptor;
        }
        ObjectStreamClass localClassDescriptor = ObjectStreamClass.lookup(localClass);
        if (localClassDescriptor != null) {
            final long localSUID = localClassDescriptor.getSerialVersionUID();
            final long streamSUID = resultClassDescriptor.getSerialVersionUID();
            if (streamSUID != localSUID) {
                System.err.println("Potentially Fatal Deserialization Operation.");
                resultClassDescriptor = localClassDescriptor;
            }
        }
        return resultClassDescriptor;
    }
}

希望能帮助到你

(这篇文章的学分)

于 2016-12-06T02:08:23.413 回答