卡拉夫:我自己的罐子里缺少课程

时间:2016-07-26 18:38:58

标签: maven osgi apache-karaf karaf maven-archetype

我使用camel-archetype-blueprint maven archetype创建了一个OSGi包。然后我尝试将其安装到Karaf中,但捆绑包将进入GracePeriod。在运行diag之后,它缺少jar文件本身内的依赖项。

好的,长版:

从原型生成的jar文件包含原型中包含的Hello和HelloBean类:

$ jar tvf myproject-1.0-SNAPSHOT.jar
   455 Tue Jul 26 11:25:10 UTC 2016 META-INF/MANIFEST.MF
     0 Tue Jul 26 11:25:10 UTC 2016 META-INF/
     0 Tue Jul 26 11:25:10 UTC 2016 META-INF/maven/
     0 Tue Jul 26 11:25:10 UTC 2016 META-INF/maven/com.petewall/
     0 Tue Jul 26 11:25:10 UTC 2016 META-INF/maven/com.petewall/myproject/
   143 Tue Jul 26 11:25:10 UTC 2016 META-INF/maven/com.petewall/myproject/pom.properties
  3418 Tue Jul 26 11:25:06 UTC 2016 META-INF/maven/com.petewall/myproject/pom.xml
     0 Tue Jul 26 11:25:10 UTC 2016 OSGI-INF/
     0 Tue Jul 26 11:25:10 UTC 2016 OSGI-INF/blueprint/
  1376 Tue Jul 26 11:20:12 UTC 2016 OSGI-INF/blueprint/blueprint-bean.xml
   961 Tue Jul 26 11:20:12 UTC 2016 OSGI-INF/blueprint/blueprint-service.xml
     0 Tue Jul 26 11:25:10 UTC 2016 com/
     0 Tue Jul 26 11:25:10 UTC 2016 com/petewall/
   143 Tue Jul 26 11:24:56 UTC 2016 com/petewall/Hello.class
  1022 Tue Jul 26 11:24:56 UTC 2016 com/petewall/HelloBean.class
   676 Tue Jul 26 11:20:12 UTC 2016 log4j.properties

我把这个jar文件放到了我的karaf实例的deploy目录中。该软件包已安装并列在bundle:list命令中。但是,当捆绑包启动时,它会进入GracePeriod。诊断它表明它缺少一个依赖:

karaf@root()> bundle:diag  98
Camel Blueprint Route (98)
--------------------------
Status: GracePeriod
Blueprint
7/26/16 6:26 PM
Missing dependencies:
(objectClass=com.petewall.Hello)

但是,甚至可以使用karaf的exports命令找到这些类:

karaf@root()> exports
Package Name                     | Version        | ID | Bundle Name
-----------------------------------------------------------------------------
...
com.petewall                     | 1.0.0.SNAPSHOT | 98 | myproject
...

classes命令:

karaf@root()> classes
...
com/petewall/Hello.class
com/petewall/HelloBean.class

我对所有这些技术(Karaf,Camel,OSGi等等)都很陌生,所以我确定我错过了一些东西。拜托,有人能指出我在正确的方向吗?

更新1: 原型生成两个XML文件,似乎定义了蓝图服务和bean。

蓝图-bean.xml:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="..." xmlns:xsi="..." xmlns:cm="..." xsi:schemaLocation="...">
  <cm:property-placeholder persistent-id="HelloBean" update-strategy="reload">
    <cm:default-properties>
      <cm:property name="greeting" value="Hi from Camel" />
    </cm:default-properties>
  </cm:property-placeholder>

  <bean id="helloBean" class="com.petewall.HelloBean">
    <property name="say" value="${greeting}"/>
  </bean>

  <camelContext id="blueprint-bean-context" xmlns="http://camel.apache.org/schema/blueprint">
    <route id="timerToLog">
      <from uri="timer:foo?period=5000"/>
      <setBody>
        <method ref="helloBean" method="hello"/>
      </setBody>
      <log message="The message contains ${body}"/>
      <to uri="mock:result"/>
    </route>
  </camelContext>
</blueprint>

蓝图-service.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="..." xmlns:xsi="..." xmlns:cm="..." xsi:schemaLocation="...">
  <reference id="helloService" interface="com.petewall.Hello" />
  <camelContext id="blueprint-service-context" xmlns="http://camel.apache.org/schema/blueprint">
    <route id="timerToLog">
      <from uri="timer:foo?period=5000"/>
      <setBody>
        <method ref="helloService" method="hello"/>
      </setBody>
      <log message="The message contains ${body}"/>
      <to uri="mock:result"/>
    </route>
  </camelContext>
</blueprint>

原型生成一个界面Hello,用于定义一种方法:String hello()HelloBean类实现该接口并使用private String say参数来更改hello()方法打印的内容。

2 个答案:

答案 0 :(得分:2)

蓝图报告的“缺失依赖”实际上是缺少OSGi服务。

很难确定,因为您尚未发布Blueprint XML,但错误消息强烈暗示了这一点。您可能在其中有一个<reference>元素,该元素引用com.petewall.Hello服务。

是否有任何捆绑包提供com.petewall.Hello服务的实例?请注意,使用此名称在包中存在类文件是无关紧要的。也许你有这个错误的方法,你的捆绑应该提供服务?你能从更高层面解释一下你正在做什么吗?

答案 1 :(得分:1)

原型似乎创建了两种不同的方法来调用bean上的方法。

第一个蓝图在本地定义HelloBean并在其上调用方法。这可以自己运行。它不会发布任何OSGi服务。

第二个蓝图引用OSGi服务并在其上调用方法。除非您安装使用该接口导出服务的捆绑包,否则将无法启动。

捆绑包的所有蓝图xmls合并为一个蓝图上下文。因此,只有在运行时中存在HelloBean服务时才会启动合并的蓝图上下文。

尝试省略第二个blueprint.xml,你的包应该可以正常运行。