Hi All:
I'm developing an app by using Camel (Cxf component inside) +Spring+Karaf.
After I deployed it into Karaf, some bus extensions always failed to
acquire.
I checked the code, in spring case, the CxfEndpoint will call "createBus()"
method of SpringBusFactory to create the bus.
And in method "createBus", the ApplicationContext object of created bus will
always a BusApplicationContext, and the original ApplicationContext will be
past as its parent.
protected ConfigurableApplicationContext createApplicationContext(String
cfgFiles[], boolean includeDefaults) {
try {
return new BusApplicationContext(cfgFiles, includeDefaults,
context, resolver);
} catch (BeansException ex) {
.
}
}
In setApplicationContext() method of created SpringBus, if Configured
ConfiguredBeanLocator is not a SpringBeanLocator, then will be replaced by a
SpringBeanLocator, the original will be discard:
ConfiguredBeanLocator loc =
getExtension(ConfiguredBeanLocator.class);
if (!(loc instanceof SpringBeanLocator)) {
setExtension(new SpringBeanLocator(applicationContext, this),
ConfiguredBeanLocator.class);
}
I checked OsgiBeanLocator and BlueprintBeanLocator class, both of them will
pass the original ConfiguredBeanLocator as a constructor Arg.
Blueprint Case:
setExtension(new
BlueprintBeanLocator(getExtension(ConfiguredBeanLocator.class), container,
context),
ConfiguredBeanLocator.class);
Normal Osgi case:
final ConfiguredBeanLocator cbl =
bus.getExtension(ConfiguredBeanLocator.class);
if (cbl instanceof ExtensionManagerImpl) {
// wire in the OSGi things
bus.setExtension(new OSGIBeanLocator(cbl, defaultContext),
ConfiguredBeanLocator.class);
}
Then in SpringBeanLocator, it uses below method to know it's in an OSGI ENV
or not:
private void loadOSGIContext(Bus b) {
try {
//use a little reflection to allow this to work without the
spring-dm jars
//for the non-osgi cases
Method m = context.getClass().getMethod("getBundleContext");
bundleContext = m.invoke(context);
if (b != null) {
@SuppressWarnings("unchecked")
Class<Object> cls = (Class<Object>)m.getReturnType();
b.setExtension(bundleContext, cls);
}
} catch (Throwable t) {
//ignore
osgi = false;
}
}
Because the context is a BusApplicationContext, so osgi field will always
set as false, so it won't try to get a bean from osgi ENV or original
ConfiguredBeanLocator if failed to get some bean.
I appreciate to get any response.
Thanks
GangLiu