当 class 存储在外部 jar 中时,如何反序列化 object?

How do I deserialize an object when its class is stored in an external jar?

我实现 Serializable 来保存 objects,像这样:

public class MyType implements Serializable {

    @Override
    public String toString() {
        return "This is a MyType";
    }

    public static void main(String[] args) {
        try {
            ObjectOutputStream outStream = new ObjectOutputStream(
                new FileOutputStream("objecturl");
            outStream.writeObject(new MyType());
            outStream.flush();
        } catch (Exception e) { e.printStackTrace(); }
    }
}

我运行那个程序一次所以MyType保存在objecturl

然后,我将 one-class 库打包到 jarurl 的 jar 中。

如果我想使用我在新程序中保存的 object,我怎样才能让我的新程序访问 MyType,给定包含 MyType.class 的 jar?


换句话说,我如何使用 jarurl 中的 jar 来允许以下内容在没有 ClassNotFoundException 的情况下工作?

public class NewProgram {

    public static void main(String[] args) {
        try {
            ObjectInputStream inStream = new ObjectInputStream(
                new FileInputStream("objecturl");
            Object o = inStream.readObject();
            System.out.println(o.toString());
        } catch (Exception e) { e.printStackTrace(); }
    }
}

其中输出为 "This is a MyType",并且 MyType 不包含在与 NewProgram 相同的库中。


显然还有其他方法可以让程序输出"This is a MyType"。我在这里主要关心的是序列化、覆盖实现的使用。

我知道它有 something to do with ClassLoaders,但我不确定它在此设置中如何工作,其中 class 的类型完全未知,但 class' s parent 已知。

我自己还没有这样做过,但从一些谷歌搜索来看,这个问题似乎有两个阶段。

  1. 创建一个可以加载有问题的 class 的类加载器。
  2. 创建(或在第三方库中找到一个现有的)ObjectInputStream 的子class 重写 resolveClass 方法以使用您的 ClassLoader 而不是自动选择的 ClassLoader。使用 ObjectInputStream 的 subclass 来读取你的文件。

https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#resolveClass%28java.io.ObjectStreamClass%29