My favorites | Sign in
Project Logo
                
Search
for
Updated Mar 13, 2010 by Rinsvind
Labels: Deprecated
PeaberryActivation  
Automatic bootstrapping of Peaberry bundles

Introduction

Every Guice application has to be bootstrapped by a small amount of code where the Injector is created and the first few objects are wired together. The goal of Peaberry Activation is to remove the need to write this bit of bootstrap code. In this way Guice users can work in a completely declarative way only having to code their Modules. Currently Peaberry Activation works only under OSGi.

Setup

Just install and start the Peaberry Activation bundle in your OSGi framework. The bundle follows the extender model and will pick up your Peaberry bundles and process them on sight.

Usage

Under OSGi the Peaberry bootstrap code is contained in a BundleActivator. This bundle activator is coded in a repeatable pattern:

public Activator implements BundleActivator {
  /*
   * Bundle roots
   */
  @Inject
  private Export<Service1> export1;
  ...
  @Inject
  private Export<ServiceN> exportN;

  @Inject 
  private Singleton1 singleton1;
  ...
  @Inject
  private SingletonN singletonN;

  public void start(BundleContext bc) {
    /* Setup Guice */
    Injector inj = Guice.createInjector(Peaberry.osgiModule(bc), new Module1(), ..., new ModuleN());

    /* Create bundle content */
    inj.injectMembers(this);

    /* Activate content. Call the relevant start()/open() methods */
    singletonM.start();
    ...
    singletonK.start();
  }

  public void stop(BundleActivator bc) {
    /* Deactivate content. Call the relevant stop()/close()/dispose() methods */
    export1.unput();
    ...
    exportN.unput();
    singletonM.stop();
    ...
    singletonK.stop();

    /* Detach dead content */
    export1 = null;
    ...
    exportN = null;
    singleton1 = null;
    ...
    singletonN = null;
  }
}

The activator is specified in the bundle manifest:

...
Bundle-Activator: com.acme.Activator
...

The OSGi framework requires that the activator class has a default constructor. It instantiates the activator and calls the start()/stop() methods to activate and deactivate the bundle.

Peaberry Activation replaces the default OSGi bootstrap hook with a Guice bootstrap module. Rather than implement a BundleActivator you need to implement a single Module and declare it inside the bundle manifest like this:

...
Bundle-Module: com.acme.Config
...

As with the activator the bootstrap module has to have a default constructor.

public class Config extends AbstractModule {
  @Override
  protected void configure() {
    bind(export(HelloImpl.class)).toProvider(service(HelloImpl.class).export());
    bind(HelloImpl.class).in(Singleton.class);
  }
}

When more than one Guice modules are needed they can be installed from the bootstrap module like this:

public class Config extends AbstractModule {
  @Override
  protected void configure() {
    install(new Module1());
    install(new ModuleN());
  }
}

The Peaberry Activation extender will instantiate the bootstrap module and pass it to a Guice Injetor. It will than use the Guice introspection SPI to discover all Export<T> bindings and all Singleton scoped bindings. These form the bundle roots. The roots are instantiated and activated upon bundle startup and deactivated and dropped upon bundle shutdown. I.e. we follow the standard startup and shutdown sequences outlined in the BundleActivator template shown above. Currently there are two minor restrictions we must follow:

If some of the bundle singletons need additional activation or deactivation we can annotate any parameter-less method of the respective singleton class as follows:

public HelloImpl implements Hello {

  public void hello(String who) {
    System.out.println("Hello " + who + "!");
  }

  @Start
  public void start() {
    System.out.println("Hello service online");
  }

  @Stop
  public void stop() {
    System.out.println("Hello service offline");
  }
}

The @Start and @Stop annotations are located in the org.ops4j.peaberry.activation package. Notice that if a method is annotated but has parameters it will be ignored. In a future version an error will be emitted for such methods.

We can annotate as many methods as we like. All @Start methods will be called in the order in which they are defined in the bundle class. Same goes for the @Stop methods.

Order and Correctness

Startup

This sequence guarantees that your bundle's internals will be fully set up before they are exposed to control flow either from OSGi clients or from your own @Start methods.

Shutdown


Sign in to add a comment
Powered by Google Project Hosting