SeamFramework.orgCommunity Documentation

Weld-OSGi - Weld OSGi integration

Design specification


Preface
1. About naming and references
1.1. References
1.2. Bundle types
2. What is this specification for ?
2.1. Contracts
2.2. What is Weld-OSGi ?
2.3. Third party dependencies and environment
I. Architecture of Weld-OSGi
1. Framework organization
2. Extension part
2.1. API bundle
2.2. Extension bundle: the puppet master
3. Integration part
3.1. SPI bundle
3.2. Integration bundle: provide Weld containers
4. Weld-OSGi features
5. Weld-OSGi workflow
6. Bean bundles life cycle
7. Bean bundle characteristics
7.1. The META-INF/bean.xml file
7.2. The Embedded-CDIContainer META-INF/Manifest.MF header
II. Programming model of Weld-OSGi
8. CDI activation in bean bundles
9. Service auto publication and injection
9.1. Service bean and auto-published OSGi service description
9.2. OSGi service auto-publication with Publish annotation
9.2.1. Service type resolution
9.2.2. Service type blacklist
9.3. OSGiService annotated or Service<T> typed injection points
9.4. OSGiServiceBean and OSGiServiceProviderBean
9.5. Clearly specify a service implementation
9.5.1. Link between qualifiers and OSGi LDAP properties
9.5.2. Filter and Properties qualifiers
9.5.3. Filter and Properties stereotypes
9.5.4. Final LDAP filter
9.5.5. Using service filtering
9.6. Bean disambiguation and annotated type processing
9.6.1. Examples
9.6.2. Justification
9.7. Contextual services
9.7.1. OSGi service scopes
9.8. Required services
9.9. Inaccessible service at runtime
10. Weld-OSGi events
10.1. CDI container lifecycle events
10.2. Bundle lifecycle events
10.3. Service lifecyle events
10.4. Bean bundle required service dependency validation events
10.5. Intra and inter bundles communication events
11. OSGi facilitation
11.1. Service registry
11.2. OSGi utilities
11.3. The registration

The extension bundle is the orchestrator of Weld-OSGi. It may be used by any application that requires Weld-OSGi. It may be just started at the beginning of a Weld-OSGi application. It requires the extension API bundle as a dependency.

The extension bundle is the heart of Weld-OSGi applications. Once it is started, provided that it finds a started integration bundle, it manages all the bean bundles. It is in charge of service automatic publishing, service injections, CDI event notifications and bundle communications.

It runs in background, it just need to be started with the OSGi environment, then everything is transparent to the user. Client bean bundles do not have to do anything in order to use Weld-OSGi functionality.

In order to perform injections, the extension bundle searches for a CDI compliant container service provider once it is started. Thus it can only work coupled with a bundle providing such a service: the integration bundle.

The extension bundle provides an extension to OSGi as an extender pattern. The extension bundle (the extender) tracks for bean bundles (the extensions) to be started. Then CDI utilities are enabled for these bean bundles over OSGi environment.

The extension bundle works that way:

BEGIN
    start
    WHILE ! integration_bundle.isStarted
        wait
    END_WHILE
    obtain_container_factory
    FOR bean_bundle : started_bundles
        manage_bean_bundle
        provide_container
    END_FOR
    WHILE integration_bundle.isStarted
        wait_event
        OnBeanBundleStart
            manage_bean_bundle
            provide_container
        OnBeanBundleStop
            unmanage_bean_bundle
    END_WHILE
    stop
    FOR bean_bundle : managed_bundles
        unmanage_bean_bundle
        stop_bean_bundle
    END_FOR
END

So this is where the magic happens and where OSGi applications become much more simple.

There are very few things to do in order to obtain a bean bundle from a bean archive or a bundle. Mostly it is just adding the missing marker files and headers in the archive:

  • Make a bean archive a bean bundle by adding special OSGi marker headers in its META-INF/Manifest.MF file.

  • Or, in the other way, make a bundle a bean bundle by adding a META-INF/bean.xml file.

Thus a bean bundle has both META-INF/bean.xml file and OSGi marker headers in its META-INF/Manifest.MF file.

However there is a few other information that Weld-OSGi might need in order to perform a correct extension. In particular a bean bundle can not be manage by the extension bundle but by his own embedded CDI container. For that there is a new manifest header.

Annotate a CDI bean class with a Publish annotation makes Weld-OSGi register this bean as a OSGi service.

Such a service is accessible through Weld-OSGi service injection and OSGi classic mechanisms.

Automatically publish a new service implementation:

@Publish
public class MyServiceImpl implements MyService {
}

However, such an implementation also provides a regular CDI managed bean, so MyServiceImpl can also be injected using CDI within the bean bundle.

Qualifier annotations might be used for both specifying auto-published services and service injection points. Such qualifiers should be seen as OSGi service properties, thus every set of qualifiers corresponds to a set of OSGi service properties and so to a OSGi service LDAP filter.

However qualifiers keep a regular meaning for the CDI generated bean of an auto-published service class.

A qualifier will generate an OSGi service property for each of its valued element (an element with a default value is always considered valued) following these rules:

Weld-OSGi ensures that every OSGiService annotated or Service<T> typed injection point matches an unique OSGiServiceBean or OSGiServiceProviderBean.

Therefore, for every bean bundle Weld-OSGi:

OSGiService annotated injection points are wrapped as:

@Inject @OSGiService @Filter(Calculated_filter) Type var_name;

The global OSGi LDAP filter of the final Filter qualifier is calculated from:

Weld-OSGi provides numerous events about OSGi events and bean bundle lifecycle events. It also allows decoupled bean bundle communication.

All these features uses CDI events mechanisms:

  • These events may be listened with a Observes annotated parameter method

    public void bindBundle(@Observes AbstractBundleEvent event) {
    }
  • These events may be fired with the regular CDI mechanisms

    BeanManager beanManager;
    ...
    beanManager.fireEvent(new BundleContainerEvents.BundleContainerInitialized(bundle.getBundleContext()));
    Event<Object> event;
    ...
    event.select(AbstractBundleEvent.class).fire(new BundleInstalled(bundle));