It doesn’t happen often that I discover something in software engineering that feels like finding your missing link at the exact time you need it. I had it when I discovered OO programming back in the 1980’s, found the standard packages that came with Java in the 1990’s and discovering Dependency Injection (DI) as a way to glue parts together with the Spring framework in the 2000’s.
Since then, DI has evolved a lot: I became to dislike Spring because of all the features and magic that were added over time, which not only binds your application to it but also disqualifies it for OSGi environments. As a result, I ended up using OSGi Declarative Services as the lightweight solution for DI, which was often enough for most OSGi based applications with or without web front-end.
A couple of months ago, for a project I was involved in, JSF was chosen as the front-end technology. This decision was not taken lightly and the application is indeed perfectly suited for JSF. However, the rest of organisation kind of demanded an OSGi based back-end which left us to bridge the gap between JSF and OSGi services. After considering various JEE/OSGi combinations (Wildfly, Glassfish, Karaf), it was decided to use a plain OSGi framework combined with CDI as the bridge between JSF and the OSGi services. CDI on OSGi is however not standardised in the OSGi enterprise specification and therefore support is limited.
A (the only?) project that tries to bring CDI to OSGi is OPS4J’s PAX-CDI. At first glance the project appeared to be promising, but in the end we did not use it. The reason for this is that it was complex to set it up, mainly because it has a lot of dependencies outside the standard APIs and it is poorly documented. In the end I just didn’t get it to work properly in combination with JSF. Furthermore, it misses some of the features we had as requirement, like injection of lists of services and the option to export bean managers via the OSGi service registry (so beans can be used by multiple JSF web bundles).
Writing the glue between OSGi and CDI ourself didn’t seem that difficult: the CDI standard provides a standard means to extend the functionality of the CDI container. Such extensions allow you to link in your own functionality at specific phases during the construction of the container. And indeed this proved to be a very elegant way of extending the CDI container to our needs. Unfortunately, bootstrapping the container is not standardized (yet), so for bootstrapping the container still some implementation specific calls and adapters were needed. But in the end we created a bundle that only depends on the Weld OSGi bundle (and its dependencies).
In the coming blogs I will explain in more detail about the requirements, set-up and design of this bundle. For those who can’t wait, you can have a look at it now on github.