May 17th, 2010, 01:56 PM
Dependent bundles restarted when using ClassPathXmlApplicationContex
We are facing a problem where bundle who's services are being consumed are redeployed/restarted when its consumer bundle is undeployed. We found that the key to reproducing this behavior is when the consumer bundle loads an application context referencing some beans from the consumed bundles using ClassPathXmlApplicationContext.
For example, we have
ServiceConsumerBundle depends on the ServiceProviderBundle and has an application context file which references regular beans and services from ServiceProviderBundle.
ServiceConsumerBundle loads the beans using:
ApplicationContex context = new ClassPathXmlApplicationContext("classpath*:/testdatafiles/inventory/inventory.devices.xml");
When ServiceConsumerBundle is undeployed, the ServiceProviderBundle also get restarted, undeployed and deployed.
If the beans are put into META-INF/spring/module-context.xml and auto wired instead of using ClassPathXmlApplicationContext, then undeployment does not restart the service bundle.
Any idea what's going on? Is this the expected behavior and if so, why?
Thanks in advance for any help.
May 19th, 2010, 01:02 PM
Any ideas on this? Any pointers are greatly appreciated.
May 20th, 2010, 02:47 PM
It is generally a bad idea to share app contexts between bundles because it kind of defeats the whole purpose of osgi. If you want to share beans between bundles you should export/import them through the osgi package exports and services.
copied from dm doc:
5.2.2. Application Context Service Publication
Once the application context creation for a bundle has completed, the application context object is automatically exported as a service available through the OSGi Service Registry. The context is published under the interface org.springframework.context.ApplicationContext (and also all of the visible super-interfaces and types implemented by the context). The published service has a service property named org.springframework.context.service.name whose value is set to the bundle symbolic name of the bundle hosting the application context. It is possible to prevent publication of the application context as a service using a directive in the bundle's manifest. See Section 6.1, “Bundle Format And Manifest Headers” for details.
Note: the application context is published as a service primarily to facilitate testing, administration, and management. Accessing this context object at runtime and invoking getBean() or similar operations is discouraged. The preferred way to access a bean defined in another application context is to export that bean as an OSGi service from the defining context, and then to import a reference to that service in the context that needs access to the service. Going via the service registry in this way ensures that a bean only sees services with compatible versions of service types, and that OSGi platform dynamics are respected.
May 21st, 2010, 03:31 PM
We have over hundred beans. What is a good approach to share beans?
I work with drudman on this issue. In our case we are using Spring Beans to represent over hundred objects, which are used as test data. The total number of classes is only 3-4, but the instance value is what changes from bean to bean. Having one bean exposed for each dataset values is not possible, due to constant increase in the dataset.
Is there a better way to solve this issue?
May 21st, 2010, 05:05 PM
It is hard to give advice with so little to go on. Are the objects in common packages or are they from a variety vendors and disparate codebases? Do they share common types or interfaces? Does the client bundle know anything about the beans it is using or only that they extend Object and uses reflection to what it needs to do?
Jun 1st, 2010, 10:22 AM
Got a workaround
We figured out a workaround (or right way) to this issue. We implemented ApplicationContextAware interface, and got ApplicationContext reference from Spring Framework. This way we need not create a new ClassPathApplicationContext. When called ApplicationContext.getBean(), this issue disappeared.