【问题标题】:Deserialization of arrays of custom type in OSGiOSGi中自定义类型数组的反序列化
【发布时间】:2011-03-29 08:51:43
【问题描述】:

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

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

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

编辑: ObjectInputStream.readObject(...) 如果尝试反序列化数组,则会抛出 ClassNotFoundException。 (我假设这个异常源自接收器捆绑包的 Bundle.loadClass(...) 方法。)

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

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

【问题讨论】:

    标签: java serialization osgi classloader


    【解决方案1】:

    我怀疑您已经直接使用 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);
    }
    

    【讨论】:

    • 没错,我们在这里遇到了这个错误......我们尝试过的一个肮脏的解决方法是使用动态导入。但是,目前我们只是避免使用数组。
    猜你喜欢
    • 2013-11-12
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    相关资源
    最近更新 更多