Creating and injecting a custom service in place of an existing service requires three things:
- Understanding the service interface
- The existing service
- The references to the service
Your custom service must implement the service interface, match references you want, and might need to invoke the existing service.
Getting components to adopt your custom service immediately can require reconfiguring their references to the service. Here you’ll flesh out service details to make these decisions.
Gathering Information on a Service
Since component service references are extension points, start with determining the service you want to override and components that use that service.
Once you know the service and components that use it, use Gogo Shell’s Service Component Runtime (SCR) to inspect the components and get the service and reference details. The Gogo Shell command
scr:info [componentName]lists the component’s attributes and service references.
Here’s an example
scr:info command and results (abbreviated with
(from sample module
and its reference to a service of type
> scr:info override.my.service.reference.OverrideMyServiceReference ... Component Description: Name: override.my.service.reference.portlet.OverrideMyServiceReferencePortlet ... Reference: _someService Interface Name: override.my.service.reference.service.api.SomeService Cardinality: 1..1 Policy: static Policy option: reluctant Reference Scope: bundle ... Component Configuration: ComponentId: 2399 State: active SatisfiedReference: _someService Target: null Bound to: 6840 Properties: component.id = 2400 component.name = override.my.service.reference.service.impl.SomeServiceImpl objectClass = [override.my.service.reference.service.api.SomeService] service.bundleid = 524 service.id = 6840 service.scope = bundle ...
scr:info results, like the ones above, contain information relevant to
injecting a custom service. Here’s what you’ll do with the information:
Gather reference configuration details (if reconfiguration is necessary)
Start with the service interface.
Step 1: Copy the Service Interface Name
The reference’s Interface Name is the service interface’s fully qualified name.
... Reference: _someService Interface Name: override.my.service.reference.service.api.SomeService ...
Copy and save the interface name, because it’s the type your custom service must implement.
Step 2: Copy the Existing Service Name
If you want to invoke the existing service along with your custom service, get the existing service name.
src:info result’s Component Configuration section lists the existing
service’s fully qualified name. For example, the
OverrideMyServiceReferencePortlet component’s references
bound to a service component whose fully qualified name is
Component Configuration: ... SatisfiedReference: _someService ... Bound to: 6840 Properties: ... component.name = override.my.service.reference.service.impl.SomeServiceImpl
component.name so you can reference the service in your
Here’s an example of referencing the service above.
@Reference ( target = "(component.name=override.my.service.reference.service.impl.SomeServiceImpl)" ) private SomeService _defaultService;
Step 3: Gather Reference Configuration Details (if reconfiguration is needed)
The service reference’s policy and policy option determine a component’s conditions for adopting a particular service.
If the reference’s policy option is
greedy, it binds to the matching, highest ranking service right away. The reference need not be reconfigured to adopt your service.
If policy is
staticand its policy option is
reluctant, however, the component requires one of the following conditions to switch from using the existing service it’s referencing to using the matching, highest ranking service (i.e., you’ll rank your custom service highest):
- The component is reactivated
- The component’s existing referenced service is unavailable
- The component’s reference is modified so that it does not match the existing service but matches your service
Reconfiguring the reference can be the quickest way for the component to adopt a new service.
Gather these details:
Component name: Find this at Component Description → Name. For example,
Component Description: Name: override.my.service.reference.portlet.OverrideMyServiceReferencePortlet ...
Reference name: The Reference value (e.g.,
Cardinality: Number of service instances the reference can bind to.
After creating your custom service (next), you’ll use the details you collected here to configure the component to use your custom service.
Congratulations on getting the details required for overriding the OSGi service!