0

I am experiencing problems with the order components are loaded when using OSGi declaratives services through Karaf.

I have this situation:

@Component
public class A implements IA
{
  doSomething() {...}
}


@Component
public class B implements IB
{}

@Component
public class C implements IC
{
  @Reference 
  IA a

  @Reference 
  (cardinality = ReferenceCardinality.MULTIPLE,
   policyOption = ReferencePolicyOption.GREEDY,
   unbind = "doUnRegister" )
  void doRegister(IB b)
  {
    a.doSomething()
  }

  void doUnregister(IB b)
  {
    ...
  }
}

A, B, and C are three distinct bundles.

When firing up Karaf, a B is registered and doRegister is called. However: service A is not ready (a is null).

I tried the following:

  1. set the start level of A to something lower than B... Did not work
  2. to pickup the registrations of B in a work-list and actually use A later when C was activated. Did not work AND the code was cluttered.
  3. searched for a way to write this requirement through the annotation on doRegister - NOT possible.
  4. I tried to use a service locator and get the context through an activate method on C - DID NOT WORK, it crashed Karaf.

I must clearly be missing something, is there anybody that have experienced similar problems and found a solution?

UPDATE: Reference A a changed into IA a. Added forgotten information on Reference B().

1 Answers1

1

Based upon the example code you provide, C wont be activated until A and B are present since the references to A and B are static, mandatory references. So start ordering is not relevant.

Also, references are set in the order they are written in the component description XML. When Bnd process the annotations into the component description XML, it writes the references out in order by the reference name. The reference name can be explicitly set and defaults to the name of the annotated member. So in your example code, a comes before doRegister, so the field a will be set before doRegister is called.

My guess is that, in your effort to reduce your actual code to this example, you have lost some important information to understand your problem. This would include the static/dynamic and mandatory/optional nature of your reference as well as the reference names.

BJ Hargrave
  • 9,324
  • 1
  • 19
  • 27
  • UPDATE: I have updated the example program with more details on the reference annotation and correct use of the interfaces. – Hans Stieglitz Jurgens Aug 08 '17 at 06:58
  • ReferenceCardinality.MULTIPLE is 0..n. So if component C starts before component B, C's reference to be will happily be satisfied by zero Bs. Also, if you look at the generated component description XML for component C, you should see the reference element for field A come before the reference element for bind method doRegister. This means that A will be bound and field a set before B is bound and doRegister called. – BJ Hargrave Aug 09 '17 at 12:39