Search code examples
eclipseosgiapache-felixequinoxdeclarative-services

Could not run Configuration Admin on Eclipse


I am trying to use Configuration Admin to pass configuration info to a bundle. I am using declarative services based on Equinox implementation of OSGI. First of all since I couldn't find the Equinox implementation of Config Admin I have installed the felix implementation so it would be great if someone have suggestion of where I could get the equinox version.

My main question is: I keep getting the following error when ever I run the program. It seems like a null 'configuration' object is being passed to my update methode.

osgi> !SESSION 2014-08-10 06:54:09.862 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.7.0_51
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=en_US
Command-line arguments:  -dev file:C:/Users/Desktop/OSGI/eclipseee/workspace1/.metadata/.plugins/org.eclipse.pde.core/configurator/dev.properties -os win32 -ws win32 -arch x86 -consoleLog -console

!ENTRY org.apache.felix.configadmin 4 0 2014-08-10 07:09:52.639
!MESSAGE Cannot use configuration de.services.logger.mtinylogger for   [org.osgi.service.cm.ManagedService, id=33, bundle=11/initial@reference:file:../workspace1/de.services.logger.mtinylogger/]: No visibility to configuration bound to initial@reference:file:../workspace1/de.init.configurator/

I have made a configurator bundle that creates the configuration object and the main content in it's activate method (called by declarative services) is:

    protected void activate(BundleContext bundleContext) throws IOException
    {
    //Retrieve a reference to the Configuration Admin service
    ServiceReference serviceReference = bundleContext.getServiceReference(ConfigurationAdmin.class.getName());  
    if(serviceReference != null)
    {
        ConfigurationAdmin configAdmin = (ConfigurationAdmin) bundleContext.getService(serviceReference);

        if(configAdmin != null)
        {
        Configuration configuration = configAdmin.getConfiguration("de.services.logger.mtinylogger");

        //Update configuration object
        Dictionary<String, Object> configProperties = new Hashtable<String, Object>();
        configProperties.put("port", 8080);

        configuration.update(configProperties);  
     }     

And the updated method inside the bundle implementing managedServices is as follows:

    @Override
@SuppressWarnings( { "rawtypes", "unchecked" } )
public void updated( Dictionary configuration ) throws ConfigurationException
{

    if( configuration != null ) {

        System.out.println(configuration.get("port"));
    }
    else
        System.out.println("configuration is equal to 'null ");
}

The strange thing is, when I stop and start the bundle being updated, it always displays' the configuration is equal to null' as if I have not already created the configuration object. What am I missing here?? I have spent almost 2 weeks trying to solve the issues with running configuration admin but it's taking too munch of my time. I would really appreciate some info about this. txs!!

Edited: Here I have added the 'activate' method of the class registering the ManagedService.

    protected void activate( BundleContext ctx )
{
    Dictionary< String, Object > properties = new Hashtable< String, Object >();

    //properties.put( Constants.SERVICE_PID, ctx.getBundle().getSymbolicName() );//optionally
    properties.put( Constants.SERVICE_PID, "de.services.logger.mtinylogger" );

    mService = ctx.registerService( ManagedService.class.getName(), this, properties );
}

Solution

  • Your problem is not that you are using the Felix bundle on Equinox. OSGi bundles that follow the standard can be used on any framework implementation.

    Your problem is that you are using the "wrong" method to create the configuration:

    configAdmin.getConfiguration("de.services.logger.mtinylogger");
    

    The problem is that this method will implicitly "bind" the configuration to this bundle (the configurator), therefore the bundle that this configuration really is for will no longer see it. In short, replace your method with this one:

    configAdmin.getConfiguration("de.services.logger.mtinylogger", null);
    

    That way, the configuration is not bound, and will be available for the intended target.

    My explanation about binding is relatively short, the OSGi specification (freely available) addresses it in greater detail.