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.
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
Field injection, type safe configuration, and more new goodies in Declarative Services
1. Field injection, type safe configuration,
and more new goodies in Declarative
Services
BJ Hargrave, IBM
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. 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="http://www.osgi.org/xmlns/scr/v1.1.0"
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. 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;
}
}
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
9. Field Injection
• Scalar cardinality
• Static policy
• Dynamic policy
@Reference
private Example target;
@Reference
private volatile Example target;
https://github.com/bjhargrave/osgice2015/blob/master/1ScalarFieldRef/src/example/command/ExampleCommand.java#L17
10. Field Injection
• Multiple cardinality
• Service type from generic signature
• SCR-managed collection implementation
• Static policy
• Dynamic policy
@Reference
private List<Example> targets;
https://github.com/bjhargrave/osgice2015/blob/master/2MultipleFieldRef/src/example/command/ExampleCommand.java#L20
@Reference
private volatile List<Example> targets;
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;
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. 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. 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();
}
}
https://github.com/bjhargrave/osgice2015/blob/master/3TypeSafeConfig/src/example/provider/ExampleImpl.java#L14
17. Component Property Types integrate with MetaType Service
• Use the new MetaType annotations to define metatype resources and
associate them with your component
https://github.com/bjhargrave/osgice2015/blob/master/4TypeSafeConfigWithMetatype/src/example/provider/ExampleImpl.java#L14
@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();
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) {
this.name = name.name();
}
}
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.name = name.name();
this.words = words;
}
https://github.com/bjhargrave/osgice2015/blob/master/6MultiplePIDs/src/example/provider/ExampleImpl.java#L13
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);
}
https://github.com/bjhargrave/osgice2015/blob/master/5Introspection/src/example/command/ExampleCommand.java#L25
23. SCR Data Transfer Objects
• DTOs are defined for
• Component descriptions - ComponentDescriptionDTO
• Component configurations - ComponentConfigurationDTO
• References - ReferenceDTO, SatisfiedReferenceDTO,
UnsatisfiedReferenceDTO
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;
}