2013-08-22 39 views
0

我按照本教程将OSGi嵌入到基于maven的应用程序中。我有一个类文件,创建并启动框架,如here所述,它可以很好地工作,因为我可以轻松获取BundleContext。从FrameworkUtil类获取BundleContext后抛出NPE

我在我的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,然后我试着打印出来,看看有什么happening-

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

所以上面的线prints- null

没有人有任何想法是什么呢null表示在这里的OSGi的条款和我能做些什么来解决这个问题?

感谢您的帮助。

回答

1

ModelProcessor类不是由OSGi classloader加载的,而是由主应用程序的Classloader(嵌入OSGi框架)加载的。如果下面你将看到一个类加载器加载的类:

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

如果你想使用里面的OSGi ModelProcessor类,你应该把它变成一个包,并把它安装到OSGi容器。

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

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

  • 我想,一个类或接口是在主项目的类路径(即嵌入OSGi容器)会在嵌入式OSGi容器的引导类路径上
  • 如果我的第一个猜测是真的,那么应该将接口引入主项目并将该接口的实现带入该包中。您可以在软件包的激活器中实例化实施并将其注册为服务
  • 在主应用程序中,您将能够通过已安装软件包的软件包上下文(或通过框架捆绑上下文)

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

+0

我很迷惑。我在我的主应用程序中启动了osgi框架,因此我假定该项目中的所有类都应该由OSGi classloader加载?对?如果是,那么为什么它没有被OSGi classloader加载?如果没有,那么我怎样才能确保该主项目中的所有类都能被OSGi classloader加载? – ferhan

+0

一旦JVM启动并且它有一个类加载器。之后,你的应用程序启动,并有一个类加载器。 JVM是您的应用类加载器的父代。如果搜索到一个类,它将在当前类加载器中首先搜索,而不是在父类中搜索。现在,如果你启动一个OSGi容器,它将打开几个类加载器,但在容器内部。我猜你的主应用程序的类加载器将是OSGi引导类加载器的父类。因此,如果您直接在主应用程序中使用某个类,则可以确定它不来自OSGi。 –

+0

OSGi与JEE服务器等较旧的解决方案不同,类加载器不在树中,而在图中。如果你在纸上绘图,你可以画一个树,直到你的主应用程序(JVM - app)和应用程序下你可以绘制一个图(OSGi包)。您只能通过捆绑线走到OSGi容器的上方或内部。 –