4.6 Referencing an OSGi Service

In an OSGi-based application, the business logic behind a controller is typically accessed through the OSGi Service Registry.

Exporting Packages

By default, Bundlor detects and exports all packages in a bundle. In this step Bundlor is told what to export from the greenpages.app bundle and which types from those packages to use in the greenpages.web bundle.

Add and save the following entry to the template.mf file in the greenpages.app project and then run the MANIFEST.MF generation on the project as explained in the section called “Creating web module metadata”.

Excluded-Exports: 
 greenpages.internal

(As before, be careful not to leave trailing spaces on the ends of lines and not to add any blank lines to the file. The second line of this entry has a leading space—do not omit it.)

Check that the package is no longer exported in the greenpages.app MANIFEST.MF file which should look something like this:

Manifest-Version: 1.0
Bundle-Name: GreenPages Service
Bundle-ManifestVersion: 2
Bundle-Vendor: SpringSource Inc.
Bundle-SymbolicName: greenpages
Tool: Bundlor 1.0.0.M6
Export-Package: greenpages;version="2.0"
Bundle-Version: 2.0

Go to the next step.

Referencing Projects and Packages

Now that the greenpages.app bundle exports the package that the Directory and Listing interfaces reside in, the greenpages.web bundle must import it. In this step you will update the Maven pom.xml file to depend on the greenpages.app bundle and import the package.

Open the pom.xml file in the greenpages.web project. (Edit the source directly by using the pom.xml tab in the editor.) In this file add the following entry (between the <dependencies> tags):

<dependency>
  <groupId>com.springsource.dmserver</groupId>
  <artifactId>greenpages.app</artifactId>
  <version>${project.version}</version>
</dependency>

Open the GreenPagesController class and import the Listing and Directory types. (Eclipse should now offer these as a Quick Fix. It it does not, set greenpages.app as a project dependency of greenpages.web in the Build Path of the web project.) The class should now compile cleanly.

The following imports should now have been added to the GreenPagesController class:

import greenpages.Directory;
import greenpages.Listing;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

Add the following package clause to the Import-Template entry in the template.mf file in the greenpages.web project. When added run the MANIFEST.MF generation on the project as described in the section called “Creating web module metadata”.

greenpages.*;version="[2.0, 2.1)"

Be careful to include the “.*” in the package pattern.

Once Bundlor has finished, go to the next step.

Deploying a PAR

Currently the dm Server instance has a single web module bundle deployed. In this step, the greenpages.web bundle is undeployed and greenpages PAR is deployed.

Right-click on the dm Server in the Servers view, and select Add and Remove Projects…. In the dialog that opens, remove the greenpages.web bundle and add the greenpages PAR to the server. When the configuration is complete, press Finish.

Eclipse automatically undeploys the greenpages.web bundle and deploys the greenpages PAR. When this happens, the deployment may fail with an error. If it does not, open the browser again at http://localhost:8080/greenpages and observe the failure which should have a root cause similar to:

org.springframework.beans.factory.NoSuchBeanDefinitionException: 
	No matching bean of type [greenpages.Directory] found for dependency: 
	expected at least 1 bean which qualifies as autowire candidate for this dependency. 
	Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

This error is caused by there being no instance of Directory to inject into the controller. The next section will supply one.

Referencing an OSGi Service

There is no instance of Directory to be injected into the controller. In the GreenPages application, it is intended that this implementation is used through an interface in the OSGi Service Registry. Using a service in the Service Registry enables another bundle to provide an implementation without revealing the implementation or the provider to all clients of the service. dm Server supports the use of the Spring DM namespace for referencing elements in the OSGi Service Registry. This step adds an OSGi Service Reference to an implementation of the Directory interface.

In the webapp/WEB-INF/applicationContext.xml file in the greenpages.web projects add a reference to a greenpages.Directory instance in the OSGi service registry using the <osgi:reference/> tag as follows:

<osgi:reference id="directory" interface="greenpages.Directory"/>

The tools will automatically redeploy the greenpages.web bundle when the change to the bean definition has been saved. The web bundle will not completely start. After some time, the following error should occur:

<CC0001W> Mandatory reference '&directory' in bundle
  'greenpages-1-greenpages.web' version '2.0.0' is waiting for service with filter
  '(&(objectClass=greenpages.Directory)(!(com.springsource.server.app.name=*)))'.

This error indicates that there is no provider of a greenpages.Directory in the Service Registry. The next step will address this.

The error is re-issued as the dm Server instance waits for the service to be supplied. After about five minutes the server will “time-out” and the deploy will be abandoned. This same error (and time-out) will occur each time the PAR is redeployed as each change is made.

Stop the server instance by right-clicking on the server in the Servers view and selecting Stop. This will avoid unnecessary delays as changes are made.