2.5. Provider Bundle
Overview
This section explains how to set up a Maven project for a typical provider bundle.
The
hello-paris-impl
bundle exemplifies a provider bundle, which provides the implementation of an API. The provider does not export any of its own packages, because the implementation classes are private. But the provider does instantiate and export an OSGi service, which is accessed through the HelloParis
interface.
Directory structure
The
hello-paris-impl
bundle has the following directory structure:
hello-paris-impl/
|
\--src/
|
\--main/
| |
| \--java/
| | |
| | \--org/fusesource/example/hello/paris/impl/
| | |
| | \--HelloParisImpl.java
| |
| \--resources/
| |
| \--OSGI-INF/blueprint/
| |
| \--paris-svc.xml
|
\--test/
The
org.fusesource.example.hello.paris.impl
package is private. By default, the Maven bundle plug-in treats any packages containing the segments .impl
or .internal
, as private packages.
The
src/main/resources/OSGI-INF/blueprint
directory contains a single blueprint file, paris-svc.xml
. Any file matching the pattern, *.xml
, in this directory is assumed to be a blueprint configuration file.
Sample implementation
The
hello-paris-impl
bundle is intended to implement all of the interfaces appearing in the hello-paris
API bundle. In this example, a single HelloParisImpl
class implements the HelloParis
interface, as follows:
// Java package org.fusesource.example.hello.paris.impl; import org.fusesource.example.hello.paris.HelloParis; import org.fusesource.example.time.Clock; import org.fusesource.example.time.TimeUtil; public class HelloParisImpl implements HelloParis { protected Clock localTime = null; public String getGreeting() { return new String("Bonjour!"); } public Clock getLocalTime() { if (localTime==null) { localTime = TimeUtil.createClock(TimeUtil.TimeZone.PARIS); } return localTime; } }
Publish OSGi service
The natural way to bootstrap the
HelloParis
implementation in OSGi is to publish the class, HelloParisImpl
, as an OSGi service. Use the bean
element to create a HelloParisImpl
instance and use the service
element to publish the bean, advertising it as a service of HelloParis
type.
For example, the blueprint file,
OSGI-INF/blueprint/paris-svc.xml
, has the following contents:
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="hello-paris-impl" class="org.fusesource.example.hello.paris.impl.HelloParisImpl"/> <service ref="hello-paris-impl" interface="org.fusesource.example.hello.paris.HelloParis"/> </blueprint>
Maven dependencies
In the Maven POM file, the
hello-paris-impl
bundle defines dependencies on the following Maven artifacts:
time-util
hello-paris
Import and export rules
The following import and export rules apply to the
hello-paris-impl
bundle:
- Exporting own packages—none of the bundle's own packages should be exported; they are all private.
- Importing own packages—none of the bundle's own packages should be imported.
- Importing dependent packages—any external package dependencies must be imported.
Maven bundle plug-in settings
You can use the default export rules (that is, omitting the
Export-Package
instruction), as long as you take care to put all of your code into packages containing .impl
or .internal
(which are not exported by default). You should explicitly list the implemented API, org.fusesource.example.hello.paris
, in the Import-Package
instruction and add the provide:=true
clause to it. This signals that this bundle is acting as the provider of the hello.paris
package (and ensures that the API is imported with the correct version range—see Section 3.3, “Automatic Import Versioning”). In this case, the bundle plug-in instructions are as follows:
<instructions> <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName> <Import-Package> ${project.groupId}.hello.paris*;provide:=true, * </Import-Package> </instructions>
Generated MANIFEST.MF file
When you build the bundle using Maven, the Maven bundle plug-in automatically generates the following
MANIFEST.MF
file:
Manifest-Version: 1.0 Bundle-Name: hello-paris-impl Built-By: JBLOGGS Build-Jdk: 1.5.0_08 Created-By: Apache Maven Bundle Plugin Import-Package: org.fusesource.example.hello.paris;version="[1.0,1.1)" ,org.fusesource.example.time;version="[1.0,2)",org.osgi.service.blu eprint;version="[1.0.0,2.0.0)" Export-Service: org.fusesource.example.hello.paris.HelloParis Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.fusesource.example.hello-paris-impl Tool: Bnd-1.15.0 Bnd-LastModified: 1297357383645 Bundle-Version: 1.0.0
The
Import-Package
header imports external package dependencies only—for example, org.fusesource.example.hello.paris
and org.fusesource.example.time
.
The
Export-Service
header advertises the OSGi service as a HelloParis
instance. This enables clients to find the HelloParisImpl
instance by searching for a service of HelloParis
type.