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. Note that
"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, AcmeCard, is built into the application
when it is first deployed.
To distinguish the AcmeCard 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 AcmeCard service when it is registered. The following service
registration is defined in the Blueprint XML file of the service bundle:
<service id="builtInPaymentProvider" ref="acmeCard"
interface="com.myco.providers.PaymentProvider>
<service-properties>
<entry key="type" value="built-in">
</service-properties>
</service>
<bean id="acmeCard" class="com.myco.providers.AcmeCardImpl" />
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" />