0

I'm having a problem with the following situation: The Server is waiting for one or more Functions. When a Function is bound the bindFunction is called. It needs to call doSomething() of any SpecificSystem.

When there is no SpecificSystem in my OSGi Container nothing happens which is good because the System Reference is not satisfied. The problem occurs when I add a SpecificSystem to my container. In that case the bindFunction is called before the System Reference is set leading to a NullPointerException inside bindFunction.

Is there any OSGi-way to make sure the System Reference is set when the bindFunction is executed so that I can safely call system.doSomething() inside the bindFunction?

Miguel
  • 13
  • 2

3 Answers3

1

You're treading in dangerous water here :-) You require ordering. Your code assumes the bindFunction reference is called after the system reference.

The OSGi specification guarantees that injection takes place in the lexical order of the reference name. (Of course, this is only true for the available services.)

The cheap way is to name your references so that the system reference's name is lexically lower than the name of the bindFunction reference, for example asystem or _system. The injection takes place in the lexical order.

This is ugly if course. A way to handle this is just inject the Function services and use them when needed instead of actively doing something in your bind function. This makes things more lazy which is almost always good.

Peter Kriens
  • 15,196
  • 1
  • 37
  • 55
0

In your example it looks like the System reference is mandatory. In this case your Server component will only come up if a System service is present.

Christian Schneider
  • 19,420
  • 2
  • 39
  • 64
  • That's correct but not the problem. My problem is that the Server Component comes up but when there is a Function "waiting" it triggers the bindFunction to be called before System Reference is set. Is there any way I can make sure that when my Server comes up, the System Reference is set before bindFunction is called for all the "waiting" Functions? – Miguel Feb 25 '20 at 10:38
  • DS seems to initialize alphabetically. So try to name server like aserver and it might already work. – Christian Schneider Mar 06 '20 at 15:18
0
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;

@Component(name = "ServerComponent", immediate = false)
public class Server {

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    System system;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected void bindFunction(Function func) {

    }

    @Activate
    public void activate() {

    }   
}

You can call the doSomething() in activate method. Osgi guarantees method call order with @Reference annotation.

Provided that system and function references is acquired, The activate method will be called by OSGi environment. You can call the system.doSomething() method in the activate() method. @Reference(cardinality = ReferenceCardinality.MANDATORY) annotation means that call activate method after the references is acquired.

burak isik
  • 395
  • 5
  • 6