Problem using JaxB marshalling/unmarshalling within OSGI container

I ever had a problem when want to using Jaxb in Servicemix 4.x which used OSGI. Like documentation describe on this page, we will know how to use Jaxb with apache camel. What we have to do is adding line below :

DataFormat jaxb = new JaxbDataFormat("com.foo.bar");

from("activemq:My.Queue").
  unmarshal(jaxb).
  to("mqseries:Another.Queue");

Above endpoint will route the jaxb unmarshal result to another queue. JaxbDataFormat will automatically search entity with JaxB @XMLRootElement inside package. But you will get a problem when implemented those code in OSGI. here is the error message :

org.apache.camel.RuntimeCamelException: javax.xml.bind.JAXBException: "com.foo.bar" doesnt contain ObjectFactory.class or jaxb.index
	at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1271)[95:org.apache.camel.camel-core:2.10.3]
	at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:120)[98:org.apache.camel.camel-spring:2.10.3]
	at org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:280)[98:org.apache.camel.camel-spring:2.10.3]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:97)[71:org.springframework.context:3.0.7.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:303)[71:org.springframework.context:3.0.7.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:911)[71:org.springframework.context:3.0.7.RELEASE]
	at org.springframework.osgi.context.support.AbstractOsgiBundleApplicationContext.finishRefresh(AbstractOsgiBundleApplicationContext.java:235)[77:org.springframework.osgi.core:1.2.1]
	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:358)[77:org.springframework.osgi.core:1.2.1]
	at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)[77:org.springframework.osgi.core:1.2.1]
	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)[77:org.springframework.osgi.core:1.2.1]
	at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132)[80:org.springframework.osgi.extender:1.2.1]
	at java.lang.Thread.run(Thread.java:722)[:1.7.0_09]
Caused by: javax.xml.bind.JAXBException: "com.foo.bar" doesnt contain ObjectFactory.class or jaxb.index

Cited from stackoverflow :

JAXB can’t find jaxb.index, because by default, newInstance(String) uses the current thread’s class loader (as returned by Thread.getContextClassLoader()). This doesn’t work inside Felix, because the OSGi bundles and the framework’s threads have separate class loaders.

thus, what I have to do to solved this issue is modify code below :

DataFormat jaxb = new JaxbDataFormat("com.foo.bar");

to

 //import javax.xml.bind.JAXBContext;
 //import org.apache.camel.converter.jaxb.JaxbDataFormat;
 //import org.apache.camel.spi.DataFormat;

JAXBContext jaxbContext = JAXBContext.newInstance(new Class[]{com.foo.bar.Example.class});
 DataFormat registryFormat = new JaxbDataFormat(jaxbContext);
 

Regards,

tandatangankecil

Leave a Reply

Your email address will not be published. Required fields are marked *