Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Field injection, type safe configuration, and more new goodies in Declarative Services


Published on

In the recently published Release 6 specifications, OSGi provides a significant update to the already awesome Declarative Services (DS) specification. DS is _the_ way to write and use OSGi services since it handles the details and lets you, the developer, declare what you want. The DS 1.3 specification in Release 6 includes a number of new features to make using DS even better. This talk will go over the new features to help you better understand how to use them in your bundles.

Published in: Software
  • Be the first to comment

Field injection, type safe configuration, and more new goodies in Declarative Services

  1. 1. Field injection, type safe configuration, and more new goodies in Declarative Services BJ Hargrave, IBM
  2. 2. a Component Impl a Service Impl Service Component Runtime Impl a Servicea Component Instance Component Description a Component Confguration registered service tracks dependencies declarescomponent createdby controls 0..n 0..n 0..n references 1..n 1 Configuration Admin 0..n 1 0..n 1 1 <<service>> Service Component Runtime Declarative Services • A declarative model for publishing and consuming OSGi services • Introduced in Release 4 in 2005, it greatly simplified programming OSGi services • Service Component Runtime, SCR, is the runtime which implements the spec and manages the service components
  3. 3. Service Component • A Java class which can optionally be registered as a service and can optionally use services • Described by XML in the bundle which is processed at runtime by SCR <?xml version="1.0" encoding="UTF-8"?> <scr:component xmlns:scr="" name="example.provider.ExampleImpl" activate="activate"> <implementation class="example.provider.ExampleImpl"/> <service> <provide interface="example.api.Example"/> </service> <reference name="Log" interface="org.osgi.service.log.LogService" bind="setLog"/> </scr:component>
  4. 4. Service Component using annotations • But who wants to write XML? • So DS 1.2 added support for programming with annotations • Tools, like , process the annotations into the XML used by SCR at runtime @Component public class ExampleImpl implements Example { private Map<String, Object> properties; private LogService log; @Activate void activate(Map<String, Object> map) { properties = map; } @Override public boolean say(String message) { log.log((int) properties.get("loglevel"), message); return false; } @Reference void setLog(LogService log) { this.log = log; } }
  5. 5. Pretty cool!
  6. 6. So what is new in Declarative Services 1.3? • Field Injection • Type Safe Configuration with MetaType integration • Configuration Admin integration improvements • Multiple PIDs • Introspection • And more small improvements we don’t have time to discuss today • See 112.17 “Changes” in the DS 1.3 spec
  7. 7. Field Injection
  8. 8. Injection • Method injection • Constructor injection • Field injection @Reference void setLog(LogService log) { this.log = log; }
  9. 9. Field Injection • Scalar cardinality • Static policy • Dynamic policy @Reference private Example target; @Reference private volatile Example target;
  10. 10. Field Injection • Multiple cardinality • Service type from generic signature • SCR-managed collection implementation • Static policy • Dynamic policy @Reference private List<Example> targets; @Reference private volatile List<Example> targets;
  11. 11. Field Injection • User managed collection • Can also inject fields of types related to services and collections of those types @Reference(policy = ReferencePolicy.DYNAMIC) private final List<Example> targets = new CopyOnWriteArrayList<>(); @Reference ServiceReference<Example> sr; @Reference ComponentServiceObjects<Example> so; @Reference(service=Example.class) Map<String,Object> props; @Reference Map.Entry<Map<String,Object>,Example> tuple;
  12. 12. Type Safe Configuration
  13. 13. Component Properties • Component properties come from • Component description • Configuration Admin configuration • ComponentFactory.newInstance <property name=“myport" type="Integer" value="8080"/> Dictionary<String, Object> props = new Hashtable<>(); props.put("myport", Integer.valueOf(8081)); cm.getConfiguration("Example").update(props); Dictionary<String, Object> props = new Hashtable<>(); props.put("myport", Integer.valueOf(8082)); cf.newInstance(props);
  14. 14. Getting the property values • Activate method • But what if the configuration value for myport was of type String? Or type Long? • Type safety failure in your code • You also need to handle the case where the property is not set private int myport; @Activate void activate(Map<String, Object> props) { myport = props.containsKey("myport") ? ((Integer) props.get("myport")).intValue() : 8080; }
  15. 15. Component Property Types • Define and use your component properties in a type safe manner using annotations! @interface Props { int myport() default 8080; } @Component public class ExampleImpl implements Example { private int myport; @Activate void activate(Props props) { myport = props.myport(); } }
  16. 16. Type Safe Configuration and MetaType
  17. 17. Component Property Types integrate with MetaType Service • Use the new MetaType annotations to define metatype resources and associate them with your component @ObjectClassDefinition @interface Props { int myport() default 8080; } @Designate(ocd=Props.class) @Component public class ExampleImpl implements Example { private int myport; @Activate void activate(Props props) { myport = props.myport();
  18. 18. Multiple Configurations
  19. 19. Component properties from Configurations • DS integrates with Configuration Admin and will get component properties from a configuration with the configuration pid of the component @ObjectClassDefinition(pid = "Example") @interface Name { String name() default "Default Name"; } @Component(configurationPid = "Example") public class ExampleImpl implements Example { private String name; @Activate void activate(Name name) { =; } }
  20. 20. Sometimes we need to use multiple configurations • A component may want to use a “system” configuration as well as a specific configuration @ObjectClassDefinition(pid = “System") @interface Name { String name() default "Default Name"; } @ObjectClassDefinition(pid = "Example") @interface Words { String hello() default "Hello"; String goodbye() default "Goodbye"; } @Component(configurationPid = {“System", "Example"}) public class ExampleImpl implements Example { private String name; private Words words; @Activate void activate(Name name, Words words) { =; this.words = words; }
  21. 21. Introspection
  22. 22. Introspecting the Service Components • SCR now registers a ServiceComponentRuntime service which provides APIs to introspect the service components managed by SCR public interface ServiceComponentRuntime { Collection<ComponentDescriptionDTO> getComponentDescriptionDTOs(Bundle... bundles); ComponentDescriptionDTO getComponentDescriptionDTO(Bundle bundle, String name); Collection<ComponentConfigurationDTO> getComponentConfigurationDTOs(ComponentDescriptionDTO description); boolean isComponentEnabled(ComponentDescriptionDTO description); Promise<Void> enableComponent(ComponentDescriptionDTO description); Promise<Void> disableComponent(ComponentDescriptionDTO description); }
  23. 23. SCR Data Transfer Objects • DTOs are defined for • Component descriptions - ComponentDescriptionDTO • Component configurations - ComponentConfigurationDTO • References - ReferenceDTO, SatisfiedReferenceDTO, UnsatisfiedReferenceDTO
  24. 24. Why isn’t my component active? • You can use the DTOs to figure out why • It might be missing a required configuration or have an unsatisfied reference to a service public class ComponentConfigurationDTO extends DTO { public static final int UNSATISFIED_CONFIGURATION= 1; public static final int UNSATISFIED_REFERENCE = 2; public static final int SATISFIED = 4; public static final int ACTIVE = 8; public ComponentDescriptionDTO description; public int state; public long id; public Map<String, Object> properties; public SatisfiedReferenceDTO[] satisfiedReferences; public UnsatisfiedReferenceDTO[] unsatisfiedReferences; }
  25. 25. Fin