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

Java 如何从OSGi运行时环境中按类名字符串加载类?,java,osgi,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. 这就是我的问题:我只有包中的类加载器,我如何才能得到OSGi容器类加载器,我可以从整个OSGi容器中按名称加载类?(我希望当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.
这就是我的问题:我只有包中的类加载器,我如何才能得到OSGi容器类加载器,我可以从整个OSGi容器中按名称加载类?(我希望当OSGi启动时,它会将所有捆绑包和所有类加载到内存中,任何类都可以由OSGi容器类加载器加载,如果它确实存在并且能够加载的话)


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

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

那么,您确定包中的META-INF/MANIFEST.MF中有这样的内容吗:

Import-Package: foo.bar.com;

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


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

      任何可见类 您可以添加如下语句

      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;
      }
      
      private List>result=new ArrayList c=b.loadClass(name);
      结果.添加(c);
      }catch(classnotfounde异常){
      //没问题,这个包没有类
      }
      }
      返回结果;
      }
      
      在OSGi中,没有确定的方法只能用完全限定的类名来命名类。原因是两个bundle可以用不同的方式定义相同的类名。例如,如果捆绑包A需要1.0版的lib,而捆绑包B在2.0版中需要相同的lib,这一点很重要

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

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

      当然,您也可以简单地迭代所有这些类装入器,并尝试按名称查找类。但问题是,它不必是唯一的。因为您可以在您的案例中打印一条警告,这可能还可以

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

      您可以使用java反射按类名动态加载类。是的,我可以加载由其他Bundle导出的类。但是如何加载未导出的类?我需要得到父类加载器之类的东西?但这就是OSGi的全部要点,你不想看到任何你不导入的东西。如果您愿意,您可以使用自动导入所有可用的包如果您没有领会我的想法,我的意思是我正在创建一个工具,需要访问OSGi内存中的所有类。所以我需要导入所有其他bundle,但有些类不是由我要加载的其他bundle导出的,我该怎么办?好吧,明白了,你是对的,我还没有得到它。但那样的话,我就难倒了。我不知道如何获得非导出类。。抱歉..Christian Schneider的回复告诉您如何从任何包(包括未导出的包)加载任何类。然而,正如他指出的,类名不会是唯一的。这是模块化不可避免的结果:类的标识由其类名和加载它的模块定义。