0

I created an OSGi bundle using the camel-archetype-blueprint maven archetype. I then tried to install this into Karaf, but the bundle is going into GracePeriod. After running diag, it's missing a dependency that is inside the jar file itself.

Ok, the long version:

The jar file generated from the archetype contains the Hello and HelloBean classes that are included from the archetype:

$ 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

I dropped this jar file into the deploy directory of my karaf instance. The bundle is installed and listed in the bundle:list command. However, when the bundle starts, it goes into GracePeriod. Diagnosing it shows that it's missing a dependency:

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

However, those classes are even found using karaf's exports command:

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

And the classes command:

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

I'm very new to all of these technologies (Karaf, Camel, OSGi, etc...), so I'm sure I'm missing something. Please, can someone point me in the right direction here?

UPDATE 1: The archetype generates two XML files which seem to define the blueprint service and bean.

blueprint-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>

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>

The archetype generates an interface, Hello, that defines one method: String hello(). The HelloBean class implements that interface and uses a private String say parameter to change what the hello() method prints.

Pete
  • 557
  • 1
  • 4
  • 18

2 Answers2

2

What Blueprint reports as a "missing dependency" is actually a missing OSGi Service.

It's difficult to be sure because you haven't posted your Blueprint XML, but the error message strongly suggests this. You probably have a <reference> element in there which refers to the com.petewall.Hello service.

Does any bundle provide an instance of com.petewall.Hello as a service? Note that the presence of a class file in your bundle with this name is irrelevant. Perhaps you have this the wrong way around, and your bundle should be providing the service? Can you explain a bit more about what you're trying to do, from a high level?

Neil Bartlett
  • 23,743
  • 4
  • 44
  • 77
  • Basically, I want a bundle, loaded by Karaf, and activated on a camel timer to call a function periodically. – Pete Jul 26 '16 at 22:17
  • So what is the role of the `Hello` interface? Does this define the function that should be called periodically? I'm not familiar with Camel, but don't you have to implement the timer function using an interface defined by Camel? – Neil Bartlett Jul 26 '16 at 23:32
  • Beware, OSGi services provided by the blueprint definition won't be wired to dependencies defined in the same bundle, for that make sure you reference those internally as beans. – Achim Nierbeck Jul 27 '16 at 06:50
  • The `Hello` interface just defines a method to be invoked by the camel timer. The archetype I used to generate the project has XML files for blueprint service and bean definitions. I will update the original question to include them... – Pete Jul 27 '16 at 13:57
1

The archetype seems to have created two different styles of calling a method on a bean.

The first blueprint defines the HelloBean locally and calls a method on it. This would be able to run on its own. It does not publish any OSGi services though.

The second blueprint references an OSGi service and calls a method on it. This will not be able to start unless you install a bundle that exports a service with that interface.

All blueprint xmls of a bundle are merged together into one blueprint context. So the merged blueprint context will only start once there is HelloBean service present in your runtime.

Try to omit the second blueprint.xml and your bundle should start fine.

Christian Schneider
  • 19,420
  • 2
  • 39
  • 64