Pregunta

I'm trying to get the FelixDependencyManager working. I'm using Karaf 3 and i'm testing with 2 Bundles, one to provide the configuration information and one implementing the ManagedService-Interface and depending on this information. So everything boils down to 3 classes:

The dependent bundle has 2 classes: the first one is extending the DependencyActivatorBase class needed for using the Felix DependencyManager and implements the init method, where the component is created and configured:

public class ConfigAdminTester extends DependencyActivatorBase{

@Override
public void init(BundleContext context, DependencyManager manager)
        throws Exception {
    manager.add(createComponent()
            .setImplementation(ConfigTestImpl.class)
            .add(createConfigurationDependency()
            .setPid("test.configadmintest.testconfig"))
            .setCallbacks(null, "start", null, null)
            );
    System.out.println("ConfigAdminTester init finished");       
}

@Override
public void destroy(BundleContext context, DependencyManager manager)
        throws Exception {
}
}

The second class in the bundle is the one that should get updated by the ConfigAdmin-Service. It implements the ManagedService and has the updated-method, which should get called when deploying the bundle and when updating the configuration:

public class ConfigTestImpl implements ManagedService{
    String host;
    String port;
    int id;
    String password;

    public void start(){
    System.out.println("Host, Port, Id, Password: " + host + ", " +   port +", " + id + ", " + password);
    }
    @Override
    public void updated(@SuppressWarnings("rawtypes") Dictionary properties) throws  ConfigurationException {
        if (properties != null) {
            host= ((String)properties.get("host"));
            if (host == null) {
            throw new ConfigurationException("host", "must be specified");
            }
            port=((String)properties.get("port"));
            if (port == null) {
            throw new ConfigurationException("port", "must be specified");
            }
            id=((Integer)properties.get("id"));
            password=((String)properties.get("password"));
            System.out.println("Configuration in Bundle HttpServer was updated");
        }
        else {
            System.out.println("Properties are null");
        }    
    }

}

The second bundle has only one class, which implements the BundleActivator, gets a Reference to the ConfigAdmin-Service and creates a new configuration with the same pid the other bundle uses:

public class ConfigCreator implements BundleActivator{
    public void start(BundleContext context) throws Exception {

    @SuppressWarnings("rawtypes")
    ServiceReference serviceRef = context.getServiceReference(ConfigurationAdmin.class.getName());
    @SuppressWarnings("unchecked")
    ConfigurationAdmin configAdmin = (ConfigurationAdmin) context.getService(serviceRef);
    Configuration config = configAdmin.getConfiguration("test.configadmintest.testconfig", null);
    Dictionary <String, Object> properties = new Hashtable <String, Object>();
    properties.put("host", "test");
    properties.put("port", "test");
    properties.put("id", 1);
    properties.put("password", "test!");
    config.update(properties);
    System.out.println("config updated");
}

The problem now is that the updated method never gets called. I get the output that ConfigAdminTest init is finished and the Bundle gets activated, but the callback method start in the ConfigtestImpl never gets called. If i just declare the component without the Configuration dependency, everything works fine, the callback method is executed as it should be. The configuration is published, available (i checked with the config:list command) and valid, but it seems that somehow the configuration is not available for the dependent bundle. Any one an idea? Help greatly appreciated.

¿Fue útil?

Solución

I literally copied the three classes you provided into my IDE, and made two bundles out of them. I also included a bundle that implements ConfigurationAdmin and the DependencyManager. When I started everything, I immediately got the message:

Configuration in Bundle HttpServer was updated

So I'm not sure what went wrong here, but your code seems to be absolutely correct! Let me show you to full output of my run, including the GoGo shell and DM shell commands:

ConfigAdminTester init finished
config updated
Configuration in Bundle HttpServer was updated
Host, Port, Id, Password: test, test, 1, test!
____________________________
Welcome to Apache Felix Gogo

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (4.2.1)
    1|Active     |    1|Apache Felix Configuration Admin Service (1.8.0)
    2|Active     |    1|Apache Felix Dependency Manager (3.1.0)
    3|Active     |    1|Apache Felix Dependency Manager Shell (3.0.1)
    4|Active     |    1|Apache Felix Gogo Command (0.12.0)
    5|Active     |    1|Apache Felix Gogo Runtime (0.10.0)
    6|Active     |    1|Apache Felix Gogo Shell (0.10.0)
    7|Active     |    1|osgi.cmpn (4.3.1.201210102024)
    8|Active     |    1|xxx.stackoverflow.b1 (0.0.0)
    9|Active     |    1|xxx.stackoverflow.b2 (0.0.0)
g! dm
[8] xxx.stackoverflow.b1
  class b1.ConfigTestImpl registered
    test.configadmintest.testconfig configuration required available

g! 

Just to be sure, I did place the code in two different packages. The sample you provided does not show packages or imports, but you cannot use the default (empty) package in OSGi. Another mistake could have been some wrong import. Anyway, if you're still stuck, let me know, and I'll be happy to provide the full sourcecode.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top