Search code examples
javaosgiapache-felix

Dynamic OSGi service replacement as development aid


We are using Apache Felix annotations to handle all the OSGi stuff in our application. I have a provider class that talks to a server. I have a consumer class that does stuff with data from the server. What I want is to create another provider instance (new class implementing interface) that is for debug purposes only that returns canned responses to requests by the consumer. Ideally I would like the consumer to be unaware of this handoff. It's provider service reference would simply be replaced.

The use case: When the developer is running on a machine without access to the actual server, he presses a button in our running app to switch from the real provider instance to our debug provider instance.

What is the recommended way to accomplish this?

Example code:

public interface IProvider{
    public String getDataFromServer();
}


@Component
@Service(value=IProvider.class)
public class RealProvider implements IProvider{
    @Override
    public String getDataFromServer(){
        ...
    }
}


@Component
@Service(value=IProvider.class)
public class DebugProvider implements IProvider{
    @Override
    public String getDataFromServer(){
        return "Hello World";
    }
}


@Component
public class Consumer{
    private @Reference IProvider provider;

    public void doSomething(){
        provider.getDataFromServer();
    }
}

Solution

  • If the two providers are in separate bundles, you can stop Bundle A and start Bundle B to switch between implementations of the service.

    If the two providers are in the same bundle, you'd need to either drop down to the OSGI API and register/unregister the services manually, or create a proxy version of IProvider that has a debugMode flag and delegates to the specific implementation.