Java 从FrameworkUtil类获取BundleContext后引发的NPE

Java 从FrameworkUtil类获取BundleContext后引发的NPE,java,osgi,apache-felix,osgi-bundle,Java,Osgi,Apache Felix,Osgi Bundle,我遵循本教程将OSGi嵌入到基于maven的应用程序中。我有一个类文件,可以创建并启动前面提到的框架,它可以很好地工作,因为我可以轻松地获取BundleContext 我在pom.xml文件中添加了这个依赖项 <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.framework</artifactI

我遵循本教程将OSGi嵌入到基于maven的应用程序中。我有一个类文件,可以创建并启动前面提到的框架,它可以很好地工作,因为我可以轻松地获取BundleContext

我在pom.xml文件中添加了这个依赖项

    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.framework</artifactId>
        <version>4.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.ops4j.pax.url</groupId>
        <artifactId>pax-url-mvn</artifactId>
        <version>1.3.6</version>
    </dependency>

org.apache.felix
org.apache.felix.framework
4.2.1
org.ops4j.pax.url
pax url mvn
1.3.6
现在,当我运行整个框架时,当它到达同一个基于maven的项目中的一个新类文件时,我需要使用
BundleContext
,因此我想我可以使用这段代码来获取BundleContext`

FrameworkUtil.getBundle(ModelProcessor.class).getBundleContext()

但不知怎么的,上面的代码抛出了我的
NullPointerException
,然后我试着打印出来看看发生了什么-

System.out.println(FrameworkUtil.getBundle(ModelProcessor.class))

因此,上面的行打印-
null

有人知道null在OSGi中的含义吗?我能做些什么来解决这个问题


感谢您的帮助。

ModelProcessor类不是由OSGi类加载器加载的,而是由主应用程序(嵌入OSGi框架)的类加载器加载的。如果执行以下操作,您将看到哪个类加载器加载了该类:

System.out.println(ModelProcessor.class.getClassLoader().toString());
如果您想在OSGi中使用ModelProcessor类,您应该将其放入一个捆绑包中,并将其安装到OSGi容器中

您的下一个问题可能是:如何从OSGi容器中的捆绑包中的主应用程序访问类

我不尝试就不知道答案,但我有一些猜测:

  • 我猜主项目(嵌入OSGi容器)的类路径中的类或接口将位于嵌入OSGi容器的引导类路径上
  • 如果我的第一个猜测是真的,那么您应该将一个接口引入主项目,并将该接口的一个实现引入到该捆绑包中。您可以在bundle的Activator中实例化实现,并将其注册为服务
  • 在主应用程序中,您将能够通过已安装捆绑包的捆绑包上下文(或通过框架捆绑包上下文)访问基于接口的已注册服务

到现在为止,这是原因。现在,如果需要该捆绑包,可以通过框架对象获得它。框架对象本身也是一个包。它也有一个文本。您可以根据位置值获取捆绑包。位置标识每个捆绑包,并且您在安装捆绑包时知道捆绑包的位置:)。如果您不知道位置,则必须遍历这些包并检查它们的符号名。

我有点困惑。我已经在我的主应用程序中启动了osgi框架,所以我假设该项目中的所有类都应该由osgi classloader加载?对吗?如果是,那么为什么OSGi类加载器没有加载它?如果没有,那么我如何确保主项目中的所有类都应该由OSGi类加载器加载呢?一旦JVM启动,就有了一个类加载器。之后,你的应用程序启动,并有一个类加载器。JVM是应用程序类加载器的父级。如果搜索一个类,则首先在当前类加载器中搜索该类,而不是在父类中搜索该类。现在,如果您启动一个OSGi容器,它将在容器内打开几个类加载器。我猜您的主应用程序的类加载器将是OSGi引导类加载器的父类。因此,如果您直接在主应用程序中使用类,您可以确保它不是来自OSGi。OSGi不同于像JEE服务器这样的旧解决方案,类加载器不是在树中,而是在图中。如果你在纸上画图,你可以画一棵树,直到你的主应用程序(JVM-app)和应用程序下你可以画一个图形(OSGi捆绑包)。您只能通过捆绑布线走到OSGi容器上或里面。我明白了。。。因此,这意味着我需要将框架设置为静态,并在其他类中使用它来获取BundleContext,这是我试图避免的…:(.我遵循这一点,实际上,我需要在我的一个类B中获取BundleContext…我无法获取它,因为该类不是由OSGi类加载器加载的..但是在我的主应用程序位于同一个包中的类中,即claas A中-我正在启动OSGi框架,如本文所述。在同一个类A中,我可以使用框架对象获取BundleContext。但是在启动应用程序之后,当调用转到同一maven项目中的类B时,我需要以某种方式使用BundleContext,如果我正在使用