gpt4 book ai didi

java - OSGi 中自定义类型数组的反序列化

转载 作者:行者123 更新时间:2023-12-04 06:48:20 24 4
gpt4 key购买 nike

我正在尝试通过专用通信包将包中的对象发送到其他框架。对于通信,我使用 TCP/IP 上的 Java 标准序列化(使用 ObjectStreams)。

通信流程如下:发送者捆绑将可序列化的对象传递给发送者,发送者将序列化对象并通过 TCP/IP 将它们发送到发送者。然后接收器将反序列化接收到的对象并将它们传递给接收器包。

由于 OSGi 类加载架构与原生架构不同,我必须对类加载器进行一些小技巧:因为我假设接收器包应该知道他接收到的类(= 将它们导入或以其他方式由它的类加载器访问) ,我使用接收器的类加载器而不是发送接收器来加载类。 (通过 Bundle.loadClass(..) 方法)。
这适用于自定义类,但是,这不适用于自定义类型的数组。
(传输-接收器类加载器不知道,但接收器包知道。)

编辑: ObjectInputStream.readObject(...) 抛出 ClassNotFoundException,如果它试图反序列化一个数组。 (我假设这个异常起源于接收者捆绑的 Bundle.loadClass(...) 方法。)

它确实适用于 java.util.List 或其他 Serializable 类。它也适用于包含其他自定义类型字段的自定义类型,只要它们不是数组。

所以问题是:数组的反/序列化方式有什么不同吗?或者它们的加载方式不同?

最佳答案

我怀疑您已经直接使用 Bundle.loadClass 实现了 ObjectInputStream.resolveClass 。如果是这样,您遇到了这个问题:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6516909

基本上, ClassLoader.loadClass 从未打算用于数组类。加载数组类的最简单方法是使用 Class.forName。不幸的是,OSGi 没有简单的方法可以做到这一点。您要么需要一个 Bundle ClassLoader 代理,要么需要对类名进行一些预处理,以确保不会将数组直接传递给 loadClass:

public static Class<?> bundleClassForName(Bundle bundle, String name) throws ClassNotFoundException {
int length = name.length();
if (length > 0 && name.charAt(0) == '[') {
int pos = 1;
while (pos < length && name.charAt(pos) == '[') {
pos++;
}

if (pos < name.length()) {
if (name.charAt(pos) != 'L') {
return Class.forName(name);
}

if (name.charAt(length - 1) == ';') {
String componentName = name.substring(pos + 1, length - 1);
Class<?> klass = bundle.loadClass(componentName);
ClassLoader loader = klass.getClassLoader();
return Class.forName(name, false, loader);
}
}
}

return bundle.loadClass(name);
}

关于java - OSGi 中自定义类型数组的反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3475352/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com