这实际上听起来像是反序列化的严重缺陷?体面的反序列化器应使用导致加载的类的类加载器。给定的类加载器应仅用于顶级对象,因为还没有父对象。
因此,在这种情况下,给定的类加载器用于加载PageData。PageData的加载器用于加载TableData,而TableData的加载器必须用于加载TestObject。除非您使用的解串器确实被人脑损坏,否则没有逻辑上的原因导致失败的原因,因为这是VM用来加载类的模型。我很惊讶Java反序列化器会这样做,我认为此行为是一个严重的错误,因为它使用的规则与VM不同。
串行化是OSGi中的一个问题,因为模块化是关于隐藏实现类的。反序列化趋向于要访问这些私有类,这是模块化的对立面。但是,对此有很好的解决方案(不包括Dynamic- ImportPackage,它以比使用纯Java更复杂,更昂贵的方式恢复到JAR地狱)。基本技巧是从公共API获得一个根对象,该根对象可以访问私有/临时需要的类。嗯,这听起来不像服务吗?
看看人们对此有何看法,这是一个小示例,说明如何使用Java序列化解决问题(即ObjectInputStream和ObjectOutputStream)。在您的问题中,您提到了ObjectDecoderInputStream,这是我不熟悉的类。
设置为:
Bundle A: class a.A { B b; } (import b)
Bundle B: class b.B { C c; } (import c)
Bundle C: class c.C { }
因此,让我们首先序列化一个对象:
ByteArrayOutputStream bous = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bous);
oos.writeObject(this);
oos.close();
现在是困难的部分。我们重写resolveObject方法,这使我们有机会实际进行适当的类加载…
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bous.toByteArray())) {
Set<ClassLoader> lhs = new LinkedHashSet<ClassLoader>();
{
// Keep a set if discovered class loaders
lhs.add(getClass().getClassLoader());
}
@Override
protected Class< ? > resolveClass(ObjectStreamClass desc)
throws ClassNotFoundException, IOException {
for (ClassLoader cl : lhs) try {
Class< ? > c = cl.loadClass(name);
// we found the class, so we can use its class loader,
// it is in the proper class space if the uses constraints
// are set properly (and you're using bnd so you should be ok)
lhs.add(c.getClassLoader());
// The paranoid among us would check
// the serial uuid here ...
// long uuid = desc.getSerialVersionUID();
// Field field = c.getField("serialVersionUID");
// assert uuid == field.get(null)
return c;
} catch (Exception e) {
// Ignore
}
// Fallback (for void and primitives)
return super.resolveClass(desc);
}
};
// And Now we've successfully read the object ...
A clone = (A) in.readObject();
请注意,这仅在正确导出瞬态图的情况下才有效。即,如果您可以这样做,new TableData
那么这也应该起作用。一个不起作用的示例是,例如,如果您从接口获取实现。接口类未连接到impl。类。即,如果您具有扩展了TableData的TableDataImpl,那么您将被搞砸。在这些情况下,您需要一些服务来找到实现的“域”。
祝好运。