【问题标题】:NPE thrown after getting BundleContext from FrameworkUtil class从 FrameworkUtil 类获取 BundleContext 后抛出 NPE
【发布时间】:2013-08-22 06:28:17
【问题描述】:

我按照本教程将 OSGi 嵌入到基于 maven 的应用程序中。我有一个类文件,可以创建和启动框架,如 here 所述,它在那里工作正常,因为我能够轻松获取 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>

现在,当我运行整个框架时,当它到达同一个基于 maven 的项目中的一个新类文件时,我需要使用 BundleContext,所以我想我可以使用这段代码来获取 BundleContext `

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

但不知何故,上面的代码让我NullPointerException 然后我尝试打印出来看看发生了什么-

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

所以上面的行打印-null

有谁知道 null 在 OSGi 中的含义以及我可以做些什么来解决这个问题?

感谢您的帮助。

【问题讨论】:

    标签: java osgi apache-felix osgi-bundle


    【解决方案1】:

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

    System.out.println(ModelProcessor.class.getClassLoader().toString());
    

    如果你想在 OSGi 中使用 ModelProcessor 类,你应该把它放在一个包中,然后安装到 OSGi 容器中。

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

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

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

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

    【讨论】:

    • 我有点困惑。我已经在我的主应用程序中启动了 osgi 框架,所以我假设该项目中的所有类都应该由 OSGi 类加载器加载?对?如果是,那么为什么 OSGi 类加载器没有加载它?如果没有,那么我如何确保该主项目中的所有类都应该由 OSGi 类加载器加载?
    • 一旦 JVM 启动并且它有一个类加载器。之后,您的应用程序启动,并且还有一个类加载器。 JVM 是您的应用程序类加载器的父级。如果搜索一个类,则首先在当前类加载器中搜索它,而不是在父类中搜索。现在,如果您启动一个 OSGi 容器,它将在容器内打开几个类加载器。我猜你的主应用程序的类加载器将是 OSGi 引导类加载器的父级。因此,如果您直接在主应用程序中使用一个类,您可以确定它不是来自 OSGi。
    • OSGi 与 JEE 服务器等较旧的解决方案不同,后者的类加载器不在树中,而是在图中。如果你在纸上画画,你可以画一棵树,直到你的主应用程序(JVM - 应用程序),在应用程序下你可以画一个图表(OSGi 包)。您只能通过捆绑布线向上或进入 OSGi 容器。
    • 我明白了...所以这意味着我需要将框架设为静态并在其他类中使用它来获取 BundleContext 并且我试图避免... :(。我在关注这个tutorial
    • 实际上,我需要在我的 B 类之一中获取 BundleContext ......我无法得到它,因为 OSGi 类加载器没有加载该类。但是在类中我的主要应用程序位于与 claas A 相同的包中 - 我正在启动 OSGi 框架,就像在 tutorial 中提到的那样。在同一个类A中,我可以使用框架对象获取BundleContext。但是在我启动我的应用程序并且当调用在同一个maven项目中转到我的类B时,我需要以某种方式使用BundleContext,如果我正在使用跨度>
    猜你喜欢
    • 2013-07-24
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多