1

OSGi 如何解决问题1将使用 OSGi 自定义类加载器从捆绑包中加载的类转换为从 rt.jar 加载的类?rt.jar 是否也加载了自定义类加载器,而不是系统类加载器?

UPD1

由于 ClassLoader.java 中的以下代码,我似乎无法使用自定义类加载器加载 rt.jar 的大部分部分:

private ProtectionDomain preDefineClass(String name, ProtectionDomain protectionDomain) {
    ...
    if ((name != null) && name.startsWith("java.")) {
        throw new SecurityException("Prohibited package name: " +
        name.substring(0, name.lastIndexOf('.')));
    }
    ...
}

[1] 问题如下:使用不同类加载器加载的类被 jvm 视为完全不同的类,即使它们的字节码完全相同,因此,例如,当我们有类rt.jar!/SomeClass并在其中派生它时bundle.jar!/SomeClassChild,我们如果它们是由不同的类加载器加载的,则无法SomeClassChild转换为。SomeClass

4

2 回答 2

4

Java中没有这样的问题。当然不像问题中所说的那样。确实,由不同类加载器加载的同名类永远不会被视为同一个类,但由此并不意味着超类必须由同一个类加载器作为子类加载。

实际上,由于所有 java.* 类,包括 Object,都来自引导类加载器,并且应用程序中没有用户类由引导类加载器加载,所以在 OSGi 出现之前,甚至不可能将任何东西转换为 Object .

于 2012-05-19T13:16:20.103 回答
1
  • java.* 类是特殊的...... Java 规范要求所有以“java”开头的类。出于安全原因从引导类路径加载。
  • 来自 rt.jar 的其他类(以及包)由框架本身导出。所有框架都有一组默认值,但有一些属性允许您扩展这些默认值(org.osgi.framework.system.packages[.extra])。框架将从加载框架的类加载器或基于启动属性的引导类加载器加载这些包中的类。

神奇之处在于,OSGi 框架将所有这些包连接在一个类加载器网格中,以确保每个包都看到一个没有冲突的一致类空间,即使多个类加载器可以加载相同的类名。因此,在具有适当元数据且没有类加载技巧的 OSGi 中,类转换异常不会发生。

如果两个包绑定到相同包名的不同类加载器,那么 OSGi 框架会确保这些包不能互相看到,因为它们驻留在不同的类空间中。

于 2013-05-20T07:31:01.660 回答