Hello.

I have two components that both declare a (unique) configurationPid
via DS annotations. Here's one of them:

  
https://github.com/io7m/callisto/blob/feature/interfaces-sketch-00/com.io7m.callisto.stringtables.main/src/main/java/com/io7m/callisto/stringtables/main/CoStringTableProvider.java#L60

The other is as follows:

--8<--

package com.io7m.examples.callisto;

import com.io7m.callisto.stringtables.api.CoStringTableProviderType;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

@Component(
  immediate = true,
  configurationPolicy = ConfigurationPolicy.OPTIONAL,
  configurationPid = "a.b.c.example")
public final class Example
{
  private static final Logger LOG;

  static {
    LOG = LoggerFactory.getLogger(Example.class);
  }

  public Example()
  {

  }

  @Reference
  private CoStringTableProviderType strings;

  @Activate
  public void onActivate()
  {
    LOG.debug("onActivate");
  }

  @Modified
  public void onModified(
    final Map<String, Object> configuration)
  {
    LOG.debug("onModified: {}", configuration);
  }
}

--8<--

I have another component that tries to update the configurations of
both of those components:

--8<--

package com.io7m.examples.callisto;

import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Properties;

@Component(immediate = true)
public final class ExampleConfigurator
{
  private static final Logger LOG;

  static {
    LOG = LoggerFactory.getLogger(ExampleConfigurator.class);
  }

  public ExampleConfigurator()
  {

  }

  @Reference
  private ConfigurationAdmin configurations;

  @Activate
  public void onActivate()
    throws IOException
  {
    LOG.debug("onActivate");

    new Thread(() -> {
      try {
        Thread.sleep(2000L);

        LOG.debug("updating");

        final Configuration config =
          this.configurations.getConfiguration(
            "com.io7m.callisto.stringtables.main.provider");

        LOG.debug("config: {}", config);

        Dictionary<String, Object> props = config.getProperties();
        if (props == null) {
          props = new Hashtable<>();
        }

        props.put("SPLASH!", Long.valueOf(23L));
        LOG.debug("config.update: {}", props);
        config.update(props);
      } catch (final InterruptedException e) {
        LOG.error("interrupt: ", e);
        Thread.currentThread().interrupt();
      } catch (final IOException e) {
        LOG.error("i/o: ", e);
        throw new UncheckedIOException(e);
      }
    }).start();

    new Thread(() -> {
      try {
        Thread.sleep(3000L);

        LOG.debug("updating");

        final Configuration config =
          this.configurations.getConfiguration(
            "a.b.c.example");

        LOG.debug("config: {}", config);

        Dictionary<String, Object> props = config.getProperties();
        if (props == null) {
          props = new Hashtable<>();
        }

        props.put("SPLASH!", Long.valueOf(23L));
        LOG.debug("config.update: {}", props);
        config.update(props);
      } catch (final InterruptedException e) {
        LOG.error("interrupt: ", e);
        Thread.currentThread().interrupt();
      } catch (final IOException e) {
        LOG.error("i/o: ", e);
        throw new UncheckedIOException(e);
      }
    }).start();
  }
}

--8<--

The Example component receives the configuration update but the
CoStringTableProvider component does not! The onModified method
of CoStringTableProvider is just never called, and no exceptions
are raised by the ExampleConfigurator component either.

Calling scr:info on both components in the Gogo shell shows:

--8<--

g! scr:info 1
*** Bundle: com.io7m.callisto.stringtables.main (11)
Component Description:
  Name: com.io7m.callisto.stringtables.main.CoStringTableProvider
  Implementation Class: 
com.io7m.callisto.stringtables.main.CoStringTableProvider
  Default State: enabled
  Activation: delayed
  Configuration Policy: optional
  Activate Method: onActivate
  Deactivate Method: onDeactivate
  Modified Method: onModified
  Configuration Pid: [com.io7m.callisto.stringtables.main.provider]
  Services: 
    com.io7m.callisto.stringtables.api.CoStringTableProviderType
  Service Scope: singleton
  Reference: onResourceResolverSet
    Interface Name: com.io7m.callisto.resources.api.CoResourceResolverType
    Cardinality: 1..1
    Policy: static
    Policy option: reluctant
    Reference Scope: bundle
  Reference: onStringTableParserProviderSet
    Interface Name: 
com.io7m.callisto.stringtables.api.CoStringTableParserProviderType
    Cardinality: 1..1
    Policy: static
    Policy option: reluctant
    Reference Scope: bundle
  Component Description Properties:
  Component Configuration:
    ComponentId: 1
    State: active      
    SatisfiedReference: onResourceResolverSet
      Target: null
      Bound to:        51
      Reference Properties:
          component.id = 3
          component.name = com.io7m.callisto.resources.main.CoResourceResolver
          objectClass = [com.io7m.callisto.resources.api.CoResourceResolverType]
          service.bundleid = 16
          service.id = 51
          service.scope = bundle
    SatisfiedReference: onStringTableParserProviderSet
      Target: null
      Bound to:        49
      Reference Properties:
          component.id = 0
          component.name = 
com.io7m.callisto.stringtables.main.CoStringTableParserProvider
          objectClass = 
[com.io7m.callisto.stringtables.api.CoStringTableParserProviderType]
          service.bundleid = 11
          service.id = 49
          service.scope = bundle
    Component Configuration Properties:
        component.id = 1
        component.name = 
com.io7m.callisto.stringtables.main.CoStringTableProvider

g! scr:info 12
*** Bundle: com.io7m.examples.com.io7m.callisto.resources.example (26)
Component Description:
  Name: com.io7m.examples.callisto.Example
  Implementation Class: com.io7m.examples.callisto.Example
  Default State: enabled
  Activation: immediate
  Configuration Policy: optional
  Activate Method: onActivate
  Deactivate Method: deactivate
  Modified Method: onModified
  Configuration Pid: [a.b.c.example]
  Reference: strings
    Interface Name: com.io7m.callisto.stringtables.api.CoStringTableProviderType
    Cardinality: 1..1
    Policy: static
    Policy option: reluctant
    Reference Scope: bundle
  Component Description Properties:
  Component Configuration:
    ComponentId: 12
    State: active      
    SatisfiedReference: strings
      Target: null
      Bound to:        52
      Reference Properties:
          component.id = 1
          component.name = 
com.io7m.callisto.stringtables.main.CoStringTableProvider
          objectClass = 
[com.io7m.callisto.stringtables.api.CoStringTableProviderType]
          service.bundleid = 11
          service.id = 52
          service.scope = bundle
    Component Configuration Properties:
        SPLASH! = 23
        component.id = 12
        component.name = com.io7m.examples.callisto.Example
        service.pid = a.b.c.example

--8<--

The only practical difference I can see in those configurations is that the
Example component has a service.pid in its component configuration properties
and the CoStringTableProvider component doesn't. I should state that the
Example component is in the same bundle as the ExampleConfigurator, whilst the
CoStringTableProvider component is in a separate bundle. I'm not sure if this 
should have any effect on the configuration.

Am I doing something obviously wrong here?

M

Attachment: pgpDgDPO7gYiy.pgp
Description: OpenPGP digital signature

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to