【问题标题】:How to load a class by classname string from OSGi runtime environment?如何从 OSGi 运行时环境中按类名字符串加载类?
【发布时间】:2012-06-16 04:01:39
【问题描述】:

我正在制作一个捆绑包以插入 OSGi 以为用户提供功能:

Usercase: User input the classname string and click "list" button, the corresponding class will be decompiled and show the text on GUI for user.

所以这是我的问题:我只有我的包的类加载器,我怎样才能获得 OSGi 容器类加载器,我可以从整个 OSGi 容器中按名称加载类? (我希望当 OSGi 启动时,它会将所有的 bundle 和所有的类加载到内存中,任何类都可以被 OSGi 容器类加载器加载,如果它确实存在并且能够加载)

有人知道怎么做这个工作吗?示例代码非常感谢。

【问题讨论】:

  • 你可以使用java反射通过类名动态加载类。

标签: java osgi


【解决方案1】:

我可以看到两种可能对您有所帮助的情况。

任何可见的类

你可以添加这样的语句

DynamicImport-Package: *

到您的清单,然后尝试使用加载类

Class.forName("com.company.class");

所有类,无论是否导出

如果你真的需要找到每个可用的类,我不确定你为什么想要这个,但你可以尝试询问每个包是否“知道”给定的类。由于在这种情况下,您最终可能会得到多个具有相同名称的类,因此您可以选择正确的类。

你可以这样做

private List<Class<?>> findClass(BundleContext context, String name) {
    List<Class<?>> result = new ArrayList<Class<?>>();
    for (Bundle b : context.getBundles()) {
        try {
            Class<?> c = b.loadClass(name);
            result.add(c);
        } catch (ClassNotFoundException e) {
            // No problem, this bundle doesn't have the class
        }
    }
    return result;
}

【讨论】:

    【解决方案2】:

    在 OSGi 中没有确定的方法仅通过其完全限定的类名来命名一个类。原因是两个包可以以不同的方式定义相同的类名。例如,如果包 A 需要一个 lib v1.0 并且包 B 需要版本 2.0 中的相同库,这很重要。

    如果您也知道捆绑包,则可以命名一个类。所以你可以解决 来自 (Bundle bundle, String fqClassname) 的类

    您可以通过使用 BundleContext 来实现这一点。从包上下文中,您可以列出包,并且可以为每个包加载一个类。

    当然,您也可以简单地遍历所有这些类加载器并尝试按名称查找类。问题在于它不必是唯一的。因为您可以在您的情况下打印一个警告,这可能没问题。

    因此,您需要的关键 API 方法是: Bundle[] BundleContext.getBundles() 类 Bundle.loadClass()

    【讨论】:

      【解决方案3】:

      我不完全确定您要做什么,但假设您正在构建一个工具,该工具需要在安装在 OSGi 框架中时对所有应用程序包进行某种形式的处理,您可能需要考虑 OSGi扩展器模式

      【讨论】:

        【解决方案4】:

        我想你的包清单中有一个导入指令来获取你需要的包。如果这样做了,那么你正在寻找的所有类都应该是你的类加载器的一部分,并且按名称加载一个类应该可以工作.

        那么,您确定在您的捆绑包中的 META-INF/MANIFEST.MF 中有类似的内容吗:

        Import-Package: foo.bar.com;
        

        【讨论】:

        • 是的,我可以加载其他包导出的类。但是如何加载未导出的类?我需要获取父类加载器之类的吗?
        • 但这就是 OSGi 的重点,你不想看到任何你没有导入的东西。如果您愿意,可以使用Dynamic-Imports 自动导入所有可用的包
        • 你没有明白我的意思,我的意思是我正在创建一个需要访问 OSGi 内存中所有类的工具。所以我需要导入所有其他包,但是我要加载的其他包没有导出某些类,我该怎么办?
        • 好吧,明白了,你说得对,我没听懂。但在那种情况下,我很难过。我不知道获得非导出类的方法..对不起..
        • Christian Schneider 的回复告诉您如何从任何包中加载任何类,包括未导出的包。然而,正如他所指出的,类名不会是唯一的。这是模块化不可避免的结果:类的身份由其类名和加载它的模块定义。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-13
        • 2010-11-19
        • 2016-08-05
        • 2012-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多