Guice-OSGi

This work is being continued in the peaberry project

Purpose

Investigate using Guice to inject OSGi service dependencies as well as OSGi service implementations.

Deliverables

Guice-OSGi is a single bundle (~500k) containing the core Guice library patched to work with OSGi classloading, plus a couple of "autobinders".

org.ops4j.guice-osgi.core-0.1.0.jar
org.ops4j.guice-osgi.core-0.1.0-javadoc.jar
org.ops4j.guice-osgi.core-0.1.0-sources.jar

Online source

https://scm.ops4j.org/repos/ops4j/laboratory/users/stuart/guice-osgi

Maven


<repositories>
  <repository>
    <id>ops4j-laboratory</id>
    <url>http://repository.ops4j.org/maven2-laboratory</url>
  </repository>
</repositories>

<dependencies>
  <dependency>
    <groupId>org.ops4j.guice-osgi</groupId>
    <artifactId>org.ops4j.guice-osgi.core</artifactId>
    <version>0.1.0</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

Usage

To use Guice-OSGi your bundle activator must extend com.google.inject.osgi.InjectedActivator

You can then pull or push services as follows...

@Inject
@OSGiService
MyService unaryProxy;

@Inject
@OSGiService
Iterable<MyService> multipleProxy;

@Inject
@OSGiService("(code=simple)") /* custom LDAP filter */
MyService filtered;

@Inject
@OSGiService(interfaces = {MyService.class}) /* custom interface list */
MyOSGiListener listener;

in the case above, MyOSGiListener implements OSGiListener and has methods that will be called when a service is added/modified/removed.

@Inject
@OSGiServiceRegistration
MyService registeredService;

@Inject
@OSGiServiceRegistration("lang=en,location=uk") /* custom service properties */
MyService configuredService;

@Inject
@OSGiServiceRegistration(interfaces = {MyBaseService.class}) /* custom interface list */
MyService customizedService;

Registered OSGi services can be controlled using the static methods in the GuiceOSGi utility class (ie. enable/disable/modify).

the bundle context is always available using:

@Inject
BundleContext bc;

injections can be applied to fields or constructor/method parameters as per Guice - except in the activator itself, where only field injection is possible (as the instance is created by the OSGi framework, not Guice).

How it works

Guice-OSGi extends the normal Guice injection logic with two "autobinders", ie. special bindings that can handle almost any type marked by their binding annotation:

  1. @OSGiService autobinds to either an OSGi service proxy (backed by a ServiceTracker) or an OSGiServiceListener implementation (which is then appended to the ServiceTracker) depending on the member type being injected
  1. @OSGiServiceRegistration autobinds to a combined proxy formed from the injected implementation (discovered by normal Guice rules) and a hidden service registration controller, which allows fine-grained control of the registered service

Where possible ServiceTrackers are re-used, if you inject the same OSGi service specification multiple times (even in different forms - unary/multiple/listener) then only one ServiceTracker will be created.

Integration tests

The Guice-OSGi project in Subversion comes with its own integration test framework, which runs on Equinox and uses Cobertura (packaged as an OSGi bundle) to track coverage. The test framework uses Guice-OSGi to find and run scripted integration tests, and demonstrates a number of different ways Guice-OSGi could be used in practice.

Example

Unpack this example and type "mvn clean install pax:provision" under the top-level folder (assumes you have Maven 2.0.5 or later installed).

You should see randomized text appear every 8 seconds - if you stop the producer bundle, you should see a different message.

If you don't want to use Maven, then binary bundles are also available for manual installation onto an OSGi framework.