Examining an OSGi Service to Override

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

  1. Since component service references are extension points, start with following the tutorial Finding Extension Points to determine the service you want to override and components that use that service.

  2. 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 ...) that describe component override.my.service.reference.OverrideMyServiceReference (from sample module override-my-service-reference) and its reference to a service of type override.my.service.reference.service.api.SomeService:

> 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
...

The scr:info results, like the ones above, contain information relevant to injecting a custom service. Here’s what you’ll do with the information:

  1. Copy the service interface name

  2. Copy the existing service name

  3. 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.

The src:info result’s Component Configuration section lists the existing service’s fully qualified name. For example, the OverrideMyServiceReferencePortlet component’s references _someService is bound to a service component whose fully qualified name is override.my.service.reference.service.impl.SomeServiceImpl.

Component Configuration:
...
SatisfiedReference: _someService
  ...
  Bound to:        6840
      Properties:
        ...
        component.name = override.my.service.reference.service.impl.SomeServiceImpl

Copy the component.name so you can reference the service in your custom service.

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 static and 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):

    1. The component is reactivated
    2. The component’s existing referenced service is unavailable
    3. 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 DescriptionName. For example,

      Component Description:
          Name: override.my.service.reference.portlet.OverrideMyServiceReferencePortlet
          ...
    
  • Reference name: The Reference value (e.g., Reference: _someService).

  • 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!

OSGi Services and Dependency Injection with Declarative Services

Finding Extension Points

Gogo Shell

« Overriding OSGi ServicesCreating a Custom OSGi Service »
この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています