Issue
I need to add XML-unmarshalling ability to my Eclipse RCP plugin. I'm using JAXB to work with XML-files. It all works great if I run RCP from my IDE. Then I build my plugin with mvn clean package
and install it to my RCP with its UI. It all runs smoothly until I want my unmarshalling. In the code where I try to create JAXB context I get this exception:
javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:232)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:375)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
at my.code -skip-
The Internet told me that JAXB implementations were banned from JDK starting from Java-11. So, I need to add one to my build. Maven dependencies don't work for me because I'm dealing with Tycho. I decided to take com.sun.xml.bind
artifact from this location.
I put the ID of the artifact to my plugin's MANIFEST.MF
:
-skip-
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.14.0",
-skip-
jakarta.xml.bind;bundle-version="2.3.3",
com.sun.xml.bind;bundle-version="2.3.3"
-skip-
I've also added it to the target definition:
-skip-
<unit id="com.sun.xml.bind" version="2.3.3.v20201118-1818"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20201130205003/repository/"/>
-skip-
The environment:
eclipse.buildId=unknown
java.version=11.0.10
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US
Command-line arguments: -os win32 -ws win32 -arch x86_64 -data @noDefault
I tried to set javax.xml.bind.context.factory=com.sun.xml.bind.v2.JAXBContextFactory
in jaxb.properties
. Same result.
I tried another implementation from org.eclipse.persistence
(Moxy). The result was the same (could not find org.eclipse.persistence.jaxb.JAXBContextFactory
).
I can find those artifacts in my RCP application in the plugins
folder. Why does not my plugin see them? What am I doing wrong?
Solution
So, my problem was in this line where I wanted to create the context:
JAXBContext ctx = JAXBContext.newInstance(nodeClass);
It threw that JAXBException
because it could not find any implementation. I haven't solved the problem but I have figured out I could use a brute force workaround that is quite ok for me. I've just replaced the line with this:
JAXBContext ctx = ContextFactory.createContext(new Class[] { nodeClass }, Collections.<String, Object>emptyMap());
Imports:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import com.sun.xml.bind.v2.ContextFactory;
Answered By - Logrus
Answer Checked By - Willingham (JavaFixing Volunteer)