16.3. Accessing an OSGi Service

Overview

This section explains how to generate, build, and deploy a simple OSGi client in the OSGi container. The client finds the simple Hello World service in the OSGi registry and invokes the sayHello() method on it.

Prerequisites

In order to generate a project using the Maven Quickstart archetype, you must have the following prerequisites:
  • Maven installation—Maven is a free, open source build tool from Apache. You can download the latest version from http://maven.apache.org/download.html (minimum is 2.0.9).
  • Internet connection—whilst performing a build, Maven dynamically searches external repositories and downloads the required artifacts on the fly. In order for this to work, your build machine must be connected to the Internet.

Generating a Maven project

The maven-archetype-quickstart archetype creates a generic Maven project, which you can then customize for whatever purpose you like. To generate a Maven project with the coordinates, org.fusesource.example:osgi-client, enter the following command:
mvn archetype:create
-DarchetypeArtifactId=maven-archetype-quickstart
-DgroupId=org.fusesource.example
-DartifactId=osgi-client
The result of this command is a directory, ProjectDir/osgi-client, containing the files for the generated project.
Note
Be careful not to choose a group ID for your artifact that clashes with the group ID of an existing product! This could lead to clashes between your project's packages and the packages from the existing product (because the group ID is typically used as the root of a project's Java package names).

Customizing the POM file

You must customize the POM file in order to generate an OSGi bundle, as follows:
  1. Follow the POM customization steps described in Section 6.1, “Generating a Bundle Project”.
  2. Because the client uses the HelloWorldSvc Java interface, which is defined in the osgi-service bundle, it is necessary to add a Maven dependency on the osgi-service bundle. Assuming that the Maven coordinates of the osgi-service bundle are org.fusesource.example:osgi-service:1.0-SNAPSHOT, you should add the following dependency to the client's POM file:
    <project ... >
      ...
      <dependencies>
        ...
        <dependency>
            <groupId>org.fusesource.example</groupId>
            <artifactId>osgi-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
      </dependencies>
      ...
    </project>

Writing the Blueprint file

To add a blueprint file to your client project, first create the following sub-directories:
ProjectDir/osgi-client/src/main/resources
ProjectDir/osgi-client/src/main/resources/OSGI-INF
ProjectDir/osgi-client/src/main/resources/OSGI-INF/blueprint
Under the ProjectDir/osgi-client/src/main/resources/OSGI-INF/blueprint directory, use your favorite text editor to create the file, config.xml, and add the XML code from Example 16.6, “Blueprint File for Importing a Service”.

Example 16.6. Blueprint File for Importing a Service

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
  
  <reference id="helloWorld"
        interface="org.fusesource.example.service.HelloWorldSvc"/>
  
  <bean id="client"
        class="org.fusesource.example.client.Client"
        init-method="init">
    <property name="helloWorldSvc" ref="helloWorld"/>
  </bean>

</blueprint>
Where the reference element creates a reference manager that finds a service of HelloWorldSvc type in the OSGi registry. The bean element creates an instance of the Client class and injects the service reference as the bean property, helloWorldSvc. In addition, the init-method attribute specifies that the Client.init() method is called during the bean initialization phase (that is, after the service reference has been injected into the client bean).

Writing the client class

Under the ProjectDir/osgi-client/src/main/java/org/fusesource/example/client directory, use your favorite text editor to create the file, Client.java, and add the Java code from Example 16.7, “The Client Class”.

Example 16.7. The Client Class

package org.fusesource.example.client;

import org.fusesource.example.service.HelloWorldSvc;

public class Client {
    HelloWorldSvc helloWorldSvc;
    
    // Bean properties
    public HelloWorldSvc getHelloWorldSvc() {
        return helloWorldSvc;
    }

    public void setHelloWorldSvc(HelloWorldSvc helloWorldSvc) {
        this.helloWorldSvc = helloWorldSvc;
    }

    public void init() {
        System.out.println("OSGi client started.");
        if (helloWorldSvc != null) {
            System.out.println("Calling sayHello()");
            helloWorldSvc.sayHello();  // Invoke the OSGi service!
        }
    }

}
The Client class defines a getter and a setter method for the helloWorldSvc bean property, which enables it to receive the reference to the Hello World service by injection. The init() method is called during the bean initialization phase, after property injection, which means that it is normally possible to invoke the Hello World service within the scope of this method.

Running the client bundle

To install and run the osgi-client project, perform the following steps:
  1. Build the project—open a command prompt and change directory to ProjectDir/osgi-client. Use Maven to build the demonstration by entering the following command:
    mvn install
    If this command runs successfully, the ProjectDir/osgi-client/target directory should contain the bundle file, osgi-client-1.0-SNAPSHOT.jar.
  2. Install and start the osgi-service bundle—at the Red Hat JBoss Fuse console, enter the following command:
    JBossFuse:karaf@root> osgi:install -s file:ProjectDir/osgi-client/target/osgi-client-1.0-SNAPSHOT.jar
    Where ProjectDir is the directory containing your Maven projects and the -s flag directs the container to start the bundle right away. For example, if your project directory is C:\Projects on a Windows machine, you would enter the following command:
    JBossFuse:karaf@root> osgi:install -s file:C:/Projects/osgi-client/target/osgi-client-1.0-SNAPSHOT.jar
    Note
    On Windows machines, be careful how you format the file URL—for details of the syntax understood by the file URL handler, see Section A.1, “File URL Handler”.
  3. Client output—f the client bundle is started successfully, you should immediately see output like the following in the console:
    Bundle ID: 239
    OSGi client started.
    Calling sayHello()
    Hello World!