如何从OSGi运行时环境中按类名字符串加载类?

时间:2012-06-13 08:16:34

标签: java osgi

我正在制作一个插件来插入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.

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

任何人都知道如何做这份工作?示例代码非常受欢迎。

4 个答案:

答案 0 :(得分:10)

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

任何可见的课程

您可以添加类似

的语句
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;
}

答案 1 :(得分:8)

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

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

的类

您可以使用BundleContext实现此功能。在捆绑上下文中,您可以列出捆绑包,并为每个捆绑包添加一个类。

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

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

答案 2 :(得分:4)

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

答案 3 :(得分:0)

我想你的bundle的清单中有一个import指令来获取你需要的包。如果已经完成,那么你要查找的所有类应该是你的类加载器的一部分,并且按名称加载一个类应该有效

那么,你确定在捆绑中的META-INF / MANIFEST.MF中有这样的东西:

Import-Package: foo.bar.com;