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

Jer*_*Cai 5 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.
Run Code Online (Sandbox Code Playgroud)

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

谁知道怎么做这个工作?示例代码非常受欢迎.

Ang*_*jpt 10

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

任何可见的类

您可以添加类似的语句

DynamicImport-Package: *
Run Code Online (Sandbox Code Playgroud)

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

Class.forName("com.company.class");
Run Code Online (Sandbox Code Playgroud)

所有课程,出口与否

如果你真的需要找到所有可用的课程,我不确定你为什么要这样,但你可以尝试询问每个包是否"知道"给定的课程.因为在这种情况下你可能会得到多个具有相同名称的类,所以你可以选择正确的类.

你可以做点什么

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;
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*der 8

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

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

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

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

所以你需要的关键API方法是:Bundle [] BundleContext.getBundles()Class Bundle.loadClass()