This section explains how to set up a Maven project for an API/provider bundle.
The hello-boston bundle exemplifies an API/provider combination
bundle. The API/provider bundle exports only its API packages, while the
implementation packages are kept private. The API/provider bundle also instantiates
and exports an OSGi service, which is accessed through the HelloBoston
interface.
The hello-boston bundle has the following directory
structure:
hello-boston/
|
\--src/
|
\--main/
| |
| \--java/
| | |
| | \--org/fusesource/example/hello/boston/
| | | |
| | | \--HelloBoston.java
| | |
| | \--org/fusesource/example/hello/boston/impl/
| | |
| | \--HelloBostonImpl.java
| |
| \--resources/
| |
| \--OSGI-INF/blueprint/
| |
| \--boston-svc.xml
|
\--test/The org.fusesource.example.hello.boston package is public and all
of its classes and interfaces are exported from the bundle.
The org.fusesource.example.hello.boston.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, boston-svc.xml. Any file matching the
pattern, *.xml, in this directory is assumed to be a blueprint
configuration file.
The hello-boston bundle contains an API, which consists of the
interface, HelloBoston. The HelloBoston interface
returns a localized greeting and a Clock object that tells the
local time. It is defined as follows:
// Java
package org.fusesource.example.hello.boston;
import org.fusesource.example.time.Clock;
public interface HelloBoston {
public String getGreeting();
public Clock getLocalTime();
}The hello-boston bundle also implements the API. In this example,
a single HelloBostonImpl class implements the
HelloBoston interface, as follows:
// Java
package org.fusesource.example.hello.boston.impl;
import org.fusesource.example.hello.boston.HelloBoston;
import org.fusesource.example.time.Clock;
import org.fusesource.example.time.TimeUtil;
public class HelloBostonImpl implements HelloBoston {
protected Clock localTime = null;
public String getGreeting() {
return new String("Hello!");
}
public Clock getLocalTime() {
if (localTime==null) {
localTime = TimeUtil.createClock(TimeUtil.TimeZone.BOSTON);
}
return localTime;
}
}The natural way to bootstrap the HelloBoston implementation in
OSGi is to publish the class, HelloBostonImpl, as an OSGi service.
Use the bean element to create a HelloBostonImpl
instance and use the service element to publish the bean,
advertising it as a service of HelloBoston type.
For example, the blueprint file,
OSGI-INF/blueprint/boston-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-boston-impl"
class="org.fusesource.example.hello.boston.impl.HelloBostonImpl"/>
<service ref="hello-boston-impl"
interface="org.fusesource.example.hello.boston.HelloBoston"/>
</blueprint>In the Maven POM file, the hello-boston bundle defines
dependencies on the following Maven artifact:
time-util
The following import and export rules apply to the hello-boston
bundle:
Exporting own packages—export the public API package,
org.fusesource.example.hello.boston. Do not export the private package,org.fusesource.example.hello.boston.impl.Importing own packages—import the public API package,
org.fusesource.example.hello.boston.Importing dependent packages—any external package dependencies must be imported.
You must export the API package,
org.fusesource.example.hello.boston, by including it in the
Export-Package instruction, and add the provide:=true
clause to it. This signals that this bundle is acting as the
provider of the hello.boston 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:
Example 2.2. Plug-In Settings for API/Provider Combination
<instructions>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>*</Import-Package>
<Export-Package>
!${project.groupId}*.impl*,
!${project.groupId}*.internal*,
${project.groupId}.hello.boston*;provide:=true;version=${project.version}
</Export-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 Built-By: JBLOGGS Created-By: Apache Maven Bundle Plugin Import-Package: org.fusesource.example.hello.boston;version="[1.0,1.1) ",org.fusesource.example.time;version="[1.0,2)",org.osgi.service.blue print;version="[1.0.0,2.0.0)" Bnd-LastModified: 1297357441566 Export-Package: org.fusesource.example.hello.boston;uses:="org.fusesou rce.example.time";version="1.0" Bundle-Version: 1.0.0 Bundle-Name: hello-boston Build-Jdk: 1.5.0_08 Bundle-ManifestVersion: 2 Export-Service: org.fusesource.example.hello.boston.HelloBoston Bundle-SymbolicName: org.fusesource.example.hello-boston Tool: Bnd-1.15.0
The Import-Package header imports both the public API package,
org.fusesource.example.hello.boston, and the external package
dependencies—for example, org.fusesource.example.time.
The Export-Package header exports the public API package,
org.fusesource.example.hello.boston, while the uses
clause declares a transitive dependency on the
org.fusesource.example.time package.
The Export-Service header advertises the OSGi service as a
HelloBoston instance. This enables clients to find the
HelloBostonImpl instance by searching for a service of
HelloBoston type.








