Obtaining the application context service from spring dm and equinox

First, having to obtain the application context created by spring DM should be a rare event. The spring dm context is designed for inter-bunde communication and the primary way to access pojos in the spring dm context is through service publishing and referencing. Within a bundle, or just in your application you can create application contexts as you normally do and within this contexts you can access service using references. So the traditional way of creating contexts continues with the idea that there is a per-bunde context that you can access through services and reference publishing.  The note below assumes you need to access the spring dm context as part of the infrastructure of your application, for example, for always accessing objects at the top-level of your application in a well-known location.

Obtaining a service from spring dm and equinox may be more tricky than you think. Because spring dm by default starts application contexts asynchronously, it is possible that the application context has not been created by the time that you need it. Hence, you have a few options:

First, you can specify create-asynchronously:=true in the Spring-Context manifest header entry. However, this is extra configuration work.

Second, you can obtain a service tracker reference and use ServiceTracker.waitForService() to wait for the service to start.

Another way that has been discussed to obtain the service is to use BundleContext.getAllServiceReferences(“org.springframework.context.ApplicationContext”, “(org.springframework.context.service.name=yourbundlesymbolicname)”). However, this does directly give you a service tracker nor does it directly allow you to wait for services to be started for a specific service instance specified by the filter criteria you give in the arguments.

I consider it a best-practice to use ServiceTracker with a filter string (&(objectClass=org.springframework.context.ApplicationContext)(org.springframework.context.service.name=yourbundlesymbolicname)) and ServiceTracker.waitForService(). Using this method and a suitable timeout means that you do not have to configure your manifest header for Spring-Context to asynchronously create the contexts. Note that you must use a suitable timeout.

For the main application (implementing IApplication) application context, I would consider it a best practice to use create-asynchronously:=true. Why? For the main bundle, that application context may be the most important for your application and you must guarantee that it is started. Any dependencies on external service references will force the startup of other contexts as needed.


Popular posts from this blog

zio layers and framework integration

typescript and react types

dotty+scala.js+async: interesting options