I’m trying to use JAXB 2.2.11 in an osgi environment (Liferay DXP). I am having issues creating a JAXBContext. Based on some other sources found while researching like this and this, I have determined that in an osgi container I need to provide the correct classloader for JAXB to instantiate the context. So I have code like this:
ClassLoader cl package.with.jaxb.objects.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("package.with.jaxb.objects ", cl);
This code causes a null pointer exception with the following stack trace:
Caused by: java.lang.NullPointerException
at javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:129)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:201)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:146)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:371)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:446)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:409)
Looking at the source for ContextFinder I can see that context
must be null on line 129:
throw handleClassCastException(context.getClass(), JAXBContext.class);
I thought perhaps the problem was that my module has a dependency on jaxb-api 2.2.11 but the jaxb-impl classes are provided by rt.jar at runtime and are probably newer than 2.2.11 because Liferay DXP runs on JDK 1.8. To get around this issue, I have tried including jaxb-impl.jar 2.2.11 as a dependency in my osgi module, thinking then the jaxb-api & jaxb-impl versions would match. After that, trying to create a JAXBContent using the same code as above results in the following error:
ClassCastException: attempting to cast jar:file:/C:/Program%20Files/Java/jdk1.8.0_144/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to bundleresource://623.fwk616113009:13/javax/xml/bind/JAXBContext.class. Please make sure that you are specifying the proper ClassLoader.
By the looks of this message, the JAXBContext that is getting instantiated is from the version of JAXBContext that is loaded via rt.jar. This is very confusing to me because I would expect the version of JAXBContext loaded by my module’s classloader to be used since I’ve included jaxb-impl.jar in my module and I’ve specified my module’s classloader is the one to be used in my call to JAXBContext.newInstance. Can anyone shed some light on how I can get jaxb 2.2.11 to work in an osgi container?
*Please note that I can’t upgrade the version of jaxb-api used by my module because the JAXB code is actually in a 3rd party jar that requires jaxb 2.2.11 (I have just eliminated the 3rd party jar from the equation for now by writing some test JAXB code).