6

我正在制作一个捆绑包以插入 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 启动时,它会将所有包和所有类加载到内存中,如果 OSGi 容器类加载器确实存在并且能够加载任何类,则它可以加载)

任何人都知道如何做这项工作?示例代码受到高度赞赏。

4

4 回答 4

13

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

任何可见的类

您可以添加如下语句

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;
}
于 2012-06-13T11:55:14.990 回答
9

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

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

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

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

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

于 2012-06-13T14:27:23.983 回答
4

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

于 2012-06-13T10:29:07.573 回答
0

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

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

Import-Package: foo.bar.com;
于 2012-06-13T08:19:53.843 回答