Jenkins : JAXB usage in Jenkins plugins

Short version

If you came across a ClassNotFoundException  in your logs or in the Jenkins UI about the class com.sun.xml.internal.bind.v2.ContextFactory , then you can solve this problem by adding a system property to your instance. 

Edit the Jenkins launcher and add -Djavax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory in the JAVA_OPTS .

Long version

Problem

Some Jenkins plugins are using JAXB to deserialize configuration, reports or exchanges with external services.

When running Jenkins on Java 11, it is still possible to see this stack trace in the logs:

hudson.remoting.ProxyException: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory
	at jenkins.util.AntClassLoader.findClassInComponents(AntClassLoader.java:1374)
	at jenkins.util.AntClassLoader.findClass(AntClassLoader.java:1327)
	at jenkins.util.AntClassLoader.loadClass(AntClassLoader.java:1080)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
	at java.xml.bind/javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)
	at java.xml.bind/javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155)
	at java.xml.bind/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:276)
Caused: hudson.remoting.ProxyException: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.

This kind of exception was reported on  JENKINS-55202 - Performance Signature Plugin: JAXB API is missing with Java 11 Closed  for example. 

The ContextFactory  implementation is not existing in the library offered by the JAXB plugin. It's in fact a fallback implementation, which is not in the libraries. 

What is happening is that JAXB requires a context, which is nonexistant. To create it, JAXB is looking for a context factory implementation. Without any configuration, it will try to use com.sun.xml.internal.bind.v2.ContextFactory .

Solution

It is possible to configure JAXB to use a context factory implementation existing in the classpath.

To do so, we can define a system property to locate the implementation. The name of the system property must be javax.xml.bind.JAXBContextFactory  and the value can differ depending on the libraries available. It is possible to use com.sun.xml.bind.v2.ContextFactory which is provided by the JAXB library and JAXB plugin.

This is possible, as long as the plugin is not explicitly using the ClassLoader  to access those classes. If not, you need to see java9.wtf/class-loading and use the ClassLoader.getPlatformClassLoader  method to have access to the javax.xml.bind package.