SeamFramework.orgCommunity Documentation

Chapter 2. Getting started with Weld-OSGi

2.1. Setting up your environment
2.2. Say hello to the World: your first bean bundle
2.3. CDI usage in bean bundle: a more complex example

In this chapter you will see:

Weld-OSGi may run in an OSGi environment, you should setup one:

Try your Felix installation a bit with these three main command:

  • The lb command, that lists all the bundles in the OSGi environment, with their id and state (currently you only have the Felix framework utility bundles)

    g! lb
    START LEVEL 1
       ID|State      |Level|Name
        0|Active     |    0|System Bundle (3.2.2)
        1|Active     |    1|Apache Felix Bundle Repository (1.6.2)
        2|Active     |    1|Apache Felix Gogo Command (0.8.0)
        3|Active     |    1|Apache Felix Gogo Runtime (0.8.0)
        4|Active     |    1|Apache Felix Gogo Shell (0.8.0)
    g! 
  • The stop <bundle_id> command, that stops the corresponding bundle

    g! stop 1
    g! lb
    START LEVEL 1
       ID|State      |Level|Name
        0|Active     |    0|System Bundle (3.2.2)
        1|Resolved   |    1|Apache Felix Bundle Repository (1.6.2)
        2|Active     |    1|Apache Felix Gogo Command (0.8.0)
        3|Active     |    1|Apache Felix Gogo Runtime (0.8.0)
        4|Active     |    1|Apache Felix Gogo Shell (0.8.0)
    g! 
  • The start <bundle_id> command, that starts the corresponding bundle

    g! start 1
    g! lb
    START LEVEL 1
       ID|State      |Level|Name
        0|Active     |    0|System Bundle (3.2.2)
        1|Active     |    1|Apache Felix Bundle Repository (1.6.2)
        2|Active     |    1|Apache Felix Gogo Command (0.8.0)
        3|Active     |    1|Apache Felix Gogo Runtime (0.8.0)
        4|Active     |    1|Apache Felix Gogo Shell (0.8.0)
    g! 

Felix framework currently auto start all bundles, although it is a good thing for utility bundles it may be inconvenient with application bundles. You should configure the Felix framework by editing the Felix home conf/config.properties file:

  • Unable the auto start option by replacing the line

    felix.auto.deploy.action=install,start

    by

    #felix.auto.deploy.action=install,start
  • Ask for auto start of utility bundle by replacing the line

    #felix.auto.start.1=

    by

    felix.auto.start.1= file:bundle/org.apache.felix.bundlerepository-1.6.2.jar \
    file:bundle/org.apache.felix.gogo.command-0.8.0.jar \
    file:bundle/org.apache.felix.gogo.runtime-0.8.0.jar \
    file:bundle/org.apache.felix.gogo.shell-0.8.0.jar

Install Weld-OSGi in the Felix framework:

  • Add some bundle in the Felix framework by simply drop the corresponding jar files into the bundle directory of Felix home

  • Download the last version of Weld-OSGi here: TBA

  • Extract the five bundles into the bundle directory of Felix home

    Get Felix up to date

    Felix framework keeps a cache of old bundles and actions you performed. You may remove the Felix home felix-cache directory to avoid older versions of bundle and configuration to be taken into account when:

    • You add/remove bundles from bundle directory

    • You modify the conf/config.properties file

    • You restart the Felix framework after running some commands

  • Update the Felix framework configuration file in order to auto install the Weld-OSGi bundle by replacing the line

    #felix.auto.install.1=

    by

    felix.auto.install.1= file:bundle/weld-osgi-core-api-1.0-SNAPSHOT.jar \
    file:bundle/weld-osgi-core-extension-1.0-SNAPSHOT.jar \
    file:bundle/weld-osgi-core-spi-1.0-SNAPSHOT.jar \
    file:bundle/weld-osgi-core-mandatory-1.0-SNAPSHOT.jar \
    file:bundle/weld-osgi-core-integration-1.0-SNAPSHOT.jar
  • Check the bundle are in the OSGi environment by starting the Felix framework

    ____________________________
    Welcome to Apache Felix Gogo
    
    g! lb
    START LEVEL 1
       ID|State      |Level|Name
        0|Active     |    0|System Bundle (3.2.2)
        1|Active     |    1|Apache Felix Bundle Repository (1.6.2)
        2|Active     |    1|Apache Felix Gogo Command (0.8.0)
        3|Active     |    1|Apache Felix Gogo Runtime (0.8.0)
        4|Active     |    1|Apache Felix Gogo Shell (0.8.0)
        5|Installed  |    1|Weld-OSGi :: Core :: Extension API (1.0.0.SNAPSHOT)
        6|Installed  |    1|Weld-OSGi :: Core :: Extension Impl (1.0.0.SNAPSHOT)
        7|Installed  |    1|Weld-OSGi :: Core :: Integration API (1.0.0.SNAPSHOT)
        8|Installed  |    1|Weld-OSGi :: Core :: Mandatory (1.0.0.SNAPSHOT)
        9|Installed  |    1|Weld-OSGi :: Implementation :: Weld Integration (1.0.0.SNAPSHOT)
    g! 
  • Run the bundles Weld-OSGi :: Core :: Extension Impl and Weld-OSGi :: Implementation :: Weld Integration in order to get the Weld-OSGi running in the Felix framework

    g! start 6
    g! start 9
    g! lb
    START LEVEL 1
       ID|State      |Level|Name
        0|Active     |    0|System Bundle (3.2.2)
        1|Active     |    1|Apache Felix Bundle Repository (1.6.2)
        2|Active     |    1|Apache Felix Gogo Command (0.8.0)
        3|Active     |    1|Apache Felix Gogo Runtime (0.8.0)
        4|Active     |    1|Apache Felix Gogo Shell (0.8.0)
        5|Resolved   |    1|Weld-OSGi :: Core :: Extension API (1.0.0.SNAPSHOT)
        6|Active     |    1|Weld-OSGi :: Core :: Extension Impl (1.0.0.SNAPSHOT)
        7|Resolved   |    1|Weld-OSGi :: Core :: Integration API (1.0.0.SNAPSHOT)
        8|Resolved   |    1|Weld-OSGi :: Core :: Mandatory (1.0.0.SNAPSHOT)
        9|Active     |    1|Weld-OSGi :: Implementation :: Weld Integration (1.0.0.SNAPSHOT)
    g! 

It would be easier if these two bundles were auto started with Felix framework.

  • Modify the Felix configuration file to do so

    felix.auto.install.1= file:bundle/weld-osgi-core-api-1.0-SNAPSHOT.jar \
    file:bundle/weld-osgi-core-spi-1.0-SNAPSHOT.jar \
    file:bundle/weld-osgi-core-mandatory-1.0-SNAPSHOT.jar
    ...
    felix.auto.start.1= file:bundle/org.apache.felix.bundlerepository-1.6.2.jar \
    file:bundle/org.apache.felix.gogo.command-0.8.0.jar \
    file:bundle/org.apache.felix.gogo.runtime-0.8.0.jar \
    file:bundle/org.apache.felix.gogo.shell-0.8.0.jar \
    file:bundle/weld-osgi-core-extension-1.0-SNAPSHOT.jar \
    file:bundle/weld-osgi-core-integration-1.0-SNAPSHOT.jar
  • Try this new configuration

    ____________________________
    Welcome to Apache Felix Gogo
    
    g! lb
    START LEVEL 1
       ID|State      |Level|Name
        0|Active     |    0|System Bundle (3.2.2)
        1|Active     |    1|Apache Felix Bundle Repository (1.6.2)
        2|Active     |    1|Apache Felix Gogo Command (0.8.0)
        3|Active     |    1|Apache Felix Gogo Runtime (0.8.0)
        4|Active     |    1|Apache Felix Gogo Shell (0.8.0)
        5|Active     |    1|Weld-OSGi :: Core :: Extension Impl (1.0.0.SNAPSHOT)
        6|Active     |    1|Weld-OSGi :: Implementation :: Weld Integration (1.0.0.SNAPSHOT)
        7|Resolved   |    1|Weld-OSGi :: Core :: Extension API (1.0.0.SNAPSHOT)
        8|Resolved   |    1|Weld-OSGi :: Core :: Integration API (1.0.0.SNAPSHOT)
        9|Resolved   |    1|Weld-OSGi :: Core :: Mandatory (1.0.0.SNAPSHOT)
    g! 

It is time to test your installation with your first application bean bundle. The goal here is to provide a "Hello World!" (and "Goodbye World!") service and use CDI to inject it into the main class of your bean bundle. It will be the hello-world bundle.

First you need to write down the "Hello World!" service:

Nothing fancy here.

Next you need to write the entry point of your application (i.e the main class of the bean bundle). That is the com.sample.App.java main class

package com.sample;

import com.sample.api.HelloWorld; (1)
import org.osgi.cdi.api.extension.events.BundleContainerEvents; (2)
import javax.enterprise.event.Observes;
import javax.inject.Inject;

public class App {

    @Inject (3)
    HelloWorld helloWorld;

    public void onStartup(@Observes BundleContainerEvents.BundleContainerInitialized event) { (4)
        helloWorld.sayHello();
    }

    public void onShutdown(@Observes BundleContainerEvents.BundleContainerShutdown event) { (5)
        helloWorld.sayGoodbye();
    }
}

You import your service interface (1) and the CDI and Weld-OSGi dependencies (2). You ask CDI for an injection of the HelloWorld service (3). onStartup method(4) and onShutdown method (5) are called when CDI usage is enable for the bean bundle (4) (i.e the bean bundle application can start) or when CDI usage is disable for the bean bundle (5) (i.e the bean bundle application may stop).

Finally you should write the configuration files of your bean bundle:

Your project should now looks like that:

hello-world
      pom.xml
    - src
        - main
            - java
                - com.sample
                  App.java
                    - api
                      HelloWorld.java
                    - impl
                      HelloWorldImpl.java
            - resources
                - META-INF
                  beans.xml
                  hello-world.bnd 

It is time to try out this first bean bundle:

Congratulations, you just use CDI in an OSGi environment thank to Weld-OSGi. When you started your bean bundle Weld-OSGi started to manage it by providing it a Weld container. Once the container was completely started (and so the HelloWorld service injection completed) the onStartup method was called and the bean bundle application started.

This first bean bundle was very simple, is Weld-OSGi really enabling complex CDI usage in bean bundle? This section will pick up the hello-world example again and improve it by:

It will be the hello-world-multilingual bean bundle.

CDI usage limits in bean bundle

Every bean bundle gets its own Weld container from the extension bundle, so the CDI usage may stay within the bean bundle boundary:

Furthermore, Weld-OSGi provides Weld container to a bean bundle when it becomes active in the OSGi environment, so any bundle in another state is not managed by Weld-OSGi. And an active bean bundle has CDI usage available only after the Weld container has initialized. In the same way CDI usage is unavailable once the Weld container has shutdown. That's the reason of onStartup and onShutdown methods from previous section:

These two events are CDI events and may be observed with regular CDI mechanisms.

public void onStartup(@Observes BundleContainerEvents.BundleContainerInitialized event) {
    //CDI usage are available in the bean bundle
}

public void onShutdown(@Observes BundleContainerEvents.BundleContainerShutdown event) {
    //CDI usage are unavailable in the bean bundle
}

Trying to use CDI mechanisms before the BundleContainerEvents.BundleContainerInitialized or after the BundleContainerEvents.BundleContainerShutdown event may result in errors.

First you need to upgrade your HelloWorld service and make it multilingual:

Now you will use CDI interceptor to force the bean bundle to present itself every time he greets the World:

Now the HelloWorld service is a bit more complex and you use several CDI features.

Next you need to update the com.sample.App.java main class

package com.sample;

import com.sample.api.HelloWorld;
import com.sample.api.Language;
import org.osgi.cdi.api.extension.events.BundleContainerEvents;

import javax.enterprise.event.Observes;
import javax.inject.Inject;

public class App {

    @Inject @Language("ENGLISH") (1)
    HelloWorld helloWorldEnglish;

    @Inject @Language("FRENCH") (2)
    HelloWorld helloWorldFrench;

    @Inject @Language("GERMAN") (3)
    HelloWorld helloWorldGerman;

    public void onStartup(@Observes BundleContainerEvents.BundleContainerInitialized event) { (4)
        helloWorldEnglish.sayHello();
        helloWorldFrench.sayHello();
        helloWorldGerman.sayHello();
    }

    public void onShutdown(@Observes BundleContainerEvents.BundleContainerShutdown event) { (5)
        helloWorldEnglish.sayGoodbye();
        helloWorldFrench.sayGoodbye();
        helloWorldGerman.sayGoodbye();
    }
}

You replace the initial HelloWorld service injection by three qualified injection, one for each language (1) (2) (3). You also update onStartup and onShutdown methods to greet and say goodbye in the three languages (4) (5).

Finally you should write the configuration files of your bean bundle:

Your project should now looks like that:

hello-world-multilingual
      pom.xml
    - src
        - main
            - java
                - com.sample
                  App.java
                    - api
                      HelloWorld.java
                      Language.java
                      Presentation.java
                    - impl
                      HelloWorldEnglish.java
                      HelloWorldFrench.java
                      HelloWorldGerman.java
                      PresentationInterceptor.java
            - resources
                - META-INF
                  beans.xml
                  hello-world-multilingual.bnd 

It is time to try out these CDI features in an OSGi environment:

CDI seems to respond perfectly in an OSGi environment, thank to Weld-OSGi. But it is sad to use only one bundle for your application, in the next chapter we will see how Weld-OSGi allow to use OSGi powerfulness coupled with CDI easiness in multi bundles application.