Search code examples
xmljaxbliferayclasscastexception

How to use JAXB in Liferay , Getting ClassCastException


I have created AddSystem.java and ObjectFactory.java from xsd file. When try to create XML it is showing error. i'm using liferay and java 1.8. Let me know any more information you need.

ClassLoader classLoader=ObjectFactory.class.getClassLoader();
JAXBContext context = JAXBContext.newInstance("com.package.JaxAddSystem",classLoader);

Error:

javax.xml.bind.JAXBException: Provider class com.sun.xml.bind.v2.ContextFactory could not be instantiated: javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/C:/Program%20Files/Java/jdk1.8.0_221/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to bundleresource://4202.fwk877311379:19/javax/xml/bind/JAXBContext.class.  Please make sure that you are specifying the proper ClassLoader.      _ - with linked exception:_[javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/C:/Program%20Files/Java/jdk1.8.0_221/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to bundleresource://4202.fwk877311379:19/javax/xml/bind/JAXBContext.class.  Please make sure that you are specifying the proper ClassLoader.    ] [Sanitized]
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:129)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:307)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:478)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:435)

Solution

  • About your issue:

    javax.xml.bind.JAXBException: Provider class com.sun.xml.bind.v2.ContextFactory could not be instantiated: javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/C:/Program%20Files/Java/jdk1.8.0_221/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to bundleresource://4202.fwk877311379:19/javax/xml/bind/JAXBContext.class. Please make sure that you are specifying the proper ClassLoader. _ - with linked exception:_[javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/C:/Program%20Files/Java/jdk1.8.0_221/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to bundleresource://4202.fwk877311379:19/javax/xml/bind/JAXBContext.class. Please make sure that you are specifying the proper ClassLoader. ] [Sanitized] at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202) at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:129) at javax.xml.bind.ContextFinder.find(ContextFinder.java:307) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:478) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:435)

    It is caused because JAXBContext is being loaded from Liferay classloader (webapps/ROOT/WEB-INF/lib/jaxb-api.jar) but there is other point that the JAXBContext is being loaded from OSGI module ( bundleresource://4202.fwk877311379:19/javax/xml/bind/JAXBContext.class)

    I ran into this issue in the past and I detected that root cause of this issue is a class named "com.sun.xml.bind.v2.ContextFactory" from JAXB library. That class is being loaded from Liferay classloader because "com.sun.xml" package is included in module.framework.properties.org.osgi.framework.bootdelegation portal.properties configuration. See: https://github.com/liferay/liferay-portal/blob/b825851dd2f8b617e3d129ff8815e31825a8cc92/portal-impl/src/portal.properties#L7759-L7786

    In order to solve this issue, you can add javax.xml.* to module.framework.properties.org.osgi.framework.bootdelegation property in your portal-ext.properties.

    So you have to copy default value of module.framework.properties.org.osgi.framework.bootdelegation to your portal-ext.properties and append javax.xml.* to it.

    With this change, JAXB classes will be always loaded from Liferay classloader, avoiding all ClassCastException issues.