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.
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.
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;
}
}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>In the Maven POM file, the hello-paris-impl bundle defines
dependencies on the following Maven artifacts:
time-utilhello-paris
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.
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 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>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.








