Osgi 使用Felix依赖关系管理器创建配置依赖关系

Osgi 使用Felix依赖关系管理器创建配置依赖关系,osgi,apache-felix,Osgi,Apache Felix,我正在努力让FelixDependencyManager工作。 我正在使用Karaf 3,我正在使用2个捆绑包进行测试,一个提供配置信息,另一个实现ManagedService接口,具体取决于此信息。 因此,所有内容归结为三类: 依赖捆绑包有两个类: 第一个是扩展使用Felix DependencyManager所需的DependencyActivator基类,并实现init方法,其中创建和配置组件: public class ConfigAdminTester extends Dependen

我正在努力让FelixDependencyManager工作。 我正在使用Karaf 3,我正在使用2个捆绑包进行测试,一个提供配置信息,另一个实现ManagedService接口,具体取决于此信息。 因此,所有内容归结为三类:

依赖捆绑包有两个类: 第一个是扩展使用Felix DependencyManager所需的DependencyActivator基类,并实现init方法,其中创建和配置组件:

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 {
}
}
捆绑包中的第二个类应该由ConfigAdmin服务更新。它实现ManagedService并具有更新的方法,在部署捆绑包和更新配置时应调用该方法:

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");
        }    
    }

}
第二个bundle只有一个类,它实现BundleActivator,获取对ConfigAdmin服务的引用,并使用另一个bundle使用的相同pid创建新配置:

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");
}
公共类ConfigCreator实现BundleActivator{
public void start(BundleContext)引发异常{
@抑制警告(“原始类型”)
ServiceReference serviceRef=context.getServiceReference(ConfigurationAdmin.class.getName());
@抑制警告(“未选中”)
ConfigurationAdmin configAdmin=(ConfigurationAdmin)context.getService(serviceRef);
Configuration config=configAdmin.getConfiguration(“test.configadmintest.testconfig”,null);
字典属性=新哈希表();
属性。放置(“主机”、“测试”);
属性。放置(“端口”、“测试”);
属性。put(“id”,1);
放置(“密码”,“测试!”);
配置更新(属性);
System.out.println(“配置更新”);
}
现在的问题是,更新后的方法从未被调用。我得到的输出是ConfigAdminTest init已完成且捆绑包已激活,但ConfigtestImpl中启动的回调方法从未被调用。如果我只是声明没有配置依赖项的组件,则一切正常,回调方法按如下方式执行应该是这样的。配置已发布、可用(我使用config:list命令进行了检查)且有效,但似乎不知何故,该配置不适用于依赖包。 有人有主意吗?
非常感谢您的帮助。

我将您提供的三个类复制到我的IDE中,并用它们制作了两个捆绑包。我还包括了一个实现ConfigurationAdmin和DependencyManager的捆绑包。当我开始一切工作时,我立即得到了信息:

Configuration in Bundle HttpServer was updated
因此,我不确定这里出了什么问题,但您的代码似乎绝对正确!让我向您展示我运行的完整输出,包括GoGo shell和DM shell命令:

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! 
为了确保这一点,我确实将代码放在了两个不同的包中。您提供的示例没有显示包或导入,但您不能在OSGi中使用默认(空)包。另一个错误可能是导入错误。无论如何,如果您仍然被卡住,请告诉我,我很乐意提供完整的源代码