Writing extensible OSGi applications

If you are writing an OSGi application that is designed to be extensible, you must ensure that your service references are declared such that only the required bundles are provisioned.

This topic describes common scenarios for extensible application design, and provides guidance on how to declare the associated service references to ensure the correct provisioning of bundles.

Scenario 1

Your application is designed to be extended by one or more services that implement a specific interface, but no such services are implemented in the application when it is first deployed.

Define a <reference-list> element in the Blueprint XML file of the client bundle, with the availability attribute set to "optional". Then, when the application is later extended by adding a composite bundle that contains one or more services that implement that interface, the composite bundle will be deployed when the application is updated.

Example

An application is designed to be extended by one or more services that implement the PaymentProvider interface. No such services are implemented in the application when it is first deployed. The following reference list is defined in the Blueprint XML file of the client bundle:
<reference-list id="paymentProviderRef"
   interface="com.myco.providers.PaymentProvider"
   availability="optional" />

Scenario 2

Your application is designed to be extended by one or more services that implement a specific interface, and such a service is built into the application when it is first deployed. Define the following elements in the Blueprint XML file of the client bundle:
  • A <reference> element for the built-in service, with the availability attribute set to "mandatory".
  • A <reference-list> element for the services that will be added later, with the availability attribute set to "optional".
Then use the filter attribute on the <reference> element to distinguish between the two types of service. The filter attribute selects the required service by referencing a custom service property, which you must add to the registration entry for the built-in service in the Blueprint XML file of the service bundle
CAUTION:
Do not define only a single reference list with the availability attribute set to "mandatory". This configuration will cause all matching services in the internal bundle repository, and in any external bundle repositories, to be provisioned when the application is deployed, in addition to the intended service that is built into the application. The bundles that contain the extra matching services are added to the shared bundle space from where they might be accessed unintentionally. "Mandatory" is the default value of the availability attribute.

Example

An application is designed to be extended by one or more services that implement the PaymentProvider interface. One such service, CardSample, is built into the application when it is first deployed.

To distinguish the CardSample service from the services that are added later when the application is extended, a service property called "type", with the value "built-in", is added to the CardSample service when it is registered. The following service registration is defined in the Blueprint XML file of the service bundle:
<service id="builtInPaymentProvider" ref="cardSample"
  interface="com.myco.providers.PaymentProvider>
   <service-properties>
      <entry key="type" value="built-in">
   </service-properties>
</service>

<bean id="cardSample" class="com.myco.providers.CardSampleImpl" />

The service reference for the built-in service specifies a filter attribute for the custom service property; this ensures that only the built-in service is deployed when the application is deployed.

The following service references are defined in the Blueprint XML file of the client bundle:
<reference id="builtInPaymentProviderRef"
   interface="com.myco.providers.PaymentProvider"
   availability="mandatory"
   filter="(type=built-in)"/>

<reference-list id="extensionPaymentProviderRef"
   interface="com.myco.providers.PaymentProvider"
   availability="optional" />