camel-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Claus Ibsen (JIRA)" <>
Subject [jira] [Resolved] (CAMEL-7708) osgi - Dozer class loading works only in last bundle
Date Thu, 09 Jul 2015 11:12:04 GMT


Claus Ibsen resolved CAMEL-7708.
    Resolution: Implemented

> osgi - Dozer class loading works only in last bundle
> ----------------------------------------------------
>                 Key: CAMEL-7708
>                 URL:
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-dozer, osgi
>    Affects Versions: 2.13.2
>            Reporter: Jozef Tomek
>             Fix For: 2.16.0
> DozerTypeConverterLoader in it's init() method sets  CamelToDozerClassResolverAdapter,
properly resolving resources only within bundle being currently loaded, to Dozer's BeanContainer.getInstance().
> Because of Dozer using singletons, this DozerClassLoader implementation is then used
for mappings done in context of all bundles. This effectively means that class loading will
work only for the bundle (using dozer) that was started the last.
> Code of interest:
> {code:title=org.apache.camel.converter.dozer.DozerTypeConverterLoader|borderStyle=solid}
>  167         CamelToDozerClassResolverAdapter adapter = new CamelToDozerClassResolverAdapter(camelContext);
> 168         BeanContainer.getInstance().setClassLoader(adapter);
> {code}
> *Symptoms*
> For me the symptoms were NPE when Dozer's JAXBBeanFactory tried to create mapping-target
class instance by loading ObjectFactory class and calling the appropriate create method. Installed
CamelToDozerClassResolverAdapter was unable to load ObjectFactory residing in different bundle
(started not as the last one), which immediatelly caused NPE.
> However I would say it has to fail even when default bean creation method instead of
JAXBBeanFactory is used.
> *Workaround*
> Since I had to deliver working module that day, my quick and not very nice workaround
was to extend DozerTypeConverterLoader, override its' init() method and after calling super.init()
replace the loader set on BeanContainer.getInstance() with my custom DozerClassLoader.
> This custom loader knows what bundle it was created for, what loader was set on BeanContainer.getInstance()
before super.init() changed it \[one hopefully working for all bundles that are already started\],
and (new) one that super.init() changed it to \[one working for this new bundle\].
> This custom loader then checks what bundle context is it called from using ugly
> {code}
> ((BundleDelegatingClassLoader) Thread.currentThread().getContextClassLoader()).getBundle()
> {code}
> approach. Then it delegates call to proper dozer class loader - either one for that bundle
or fallback.

This message was sent by Atlassian JIRA

View raw message