JAXB on Java 9, 10, 11 and beyond

If you have programs that use JAXB (Java Architecture for XML Binding) and you’ve tried to compile and run them on Java versions newer than Java 8, you’ll have noticed that you get errors. There are changes in Java SE 9, 10 and 11 that you need to know about to understand and solve these errors. In this post we will take a look at what has changed and what you need to do to use JAXB on Java 9 and beyond.

The problems

Let’s first take a look at the errors that you’ll get when you try to run or compile a program that uses JAXB on the newer Java versions.

Running a JAXB program on Java SE 9 or newer

When you run a program that was compiled with JDK 8 or older on Java SE 9 or newer, you’ll get a NoClassDefFoundError that tells you that classes in the package javax.xml.bind cannot be found, for example:

Compiling a JAXB program on JDK 9 or 10

When you compile a program that uses JAXB using JDK 9 or 10, you’ll get errors indicating that the package javax.xml.bind is not visible:

Compiling a JAXB program on JDK 11 or newer

When you compile a program that uses JAXB on JDK 11 or newer, you’ll get errors indicating that the package javax.xml.bind and the classes in it do not exist at all:

Using the xjb and schemagen tools on JDK 11

The JAXB-specific xjc and schemagen tools, which you use to convert an XML Schema ( *.xsd file) to a set of Java classes and vice versa, are included with the JDK up to version 10, but have been removed in JDK 11.

When you try to use these tools with JDK 11 or newer, you’ll get a “command not found” or similar error.

The story

Java’s standard library isn’t exactly small and lightweight. In the course of the past 20+ years, many features have been added to it, mostly because at the time it was thought that it would be a good idea if Java supported a particular technology out-of-the-box.

One of these was support for XML-based web services. When Java SE 6 was released in December 2006, XML-based web services were popular, so the developers of the Java language thought it would be a good idea if Java would have support for calling web services as a standard feature. It was decided to add the necessary APIs, that were originally developed as part of Java EE, to Java SE. Among these were JAX-WS (Java API for XML-Based Web Services) and JAXB.

With today’s trend towards microservices, it’s important that the Java runtime environment is small and lightweight, so having a large runtime library with built-in support for every possible technology isn’t as advantageous anymore.

Therefore, a proposal was made in JEP-320 to remove the Java EE and CORBA modules from the JDK.

This means the following:

  • In Java SE 9 and 10, the module java.se.ee, which contains JAX-WS, JAXB and a few other Java EE APIs, is still included but is deprecated, and not included in the module path by default. You need to explicitly enable it if you want to use it.
  • In Java SE 11, the module java.se.ee has been removed. To use JAX-WS and JAXB you need to add them to your project as separate libraries.

The solutions

Of course, you want to know what exactly you need to do to use JAXB in Java SE 9 and newer. Read on to find out how to make it work.

Not recommended: Enabling the deprecated module

One way to make your JAXB program compile on JDK 9 or 10 is to explicitly enable the deprecated module java.se.ee on the command line using the --add-modules option, for example:

You can do the same thing when you run the program, for example:

This solution is not recommended however, because it will not work on JDK 11 or newer, where the module java.se.ee has been removed completely.

A better solution is to not use the java.se.ee module at all, and add JAXB to your project as a separate library, as described below.

Adding JAXB as a separate library

The proper solution is to add the JAXB as a dependency to your project – in the same was as you would have done long ago, before Java 6.

The official JAXB API dependency can be found in the Maven Central repository, so if you’re using Maven, you’ll want to add the following dependency to your project:

Like many Java EE APIs, JAXB is just an API – a specification of a number of classes and interfaces. To use JAXB you not only need to have a dependency on the API, you also need to make sure that an implementation of the API is available in the runtime environment of your program.

When your program is running in a Java EE container, there might already be an implementation of JAXB available so you won’t need to add it. When you run your program on a plain Java runtime environment, you’ll need to include an implementation yourself.

You have several options at this point. You can use the reference implementation of JAXB, which was what was formerly included in the JDK, or you can use an alternative implementation such as EclipseLink MOXy.

Using the reference implementation

There are Maven artifacts available for the official JAXB reference implementation.

The JAXB Users Guide refers to the following artifact:

Using EclipseLink MOXy

EclipseLink MOXy is an alternative implementation of the JAXB API that you might want to use. To use this, include the following dependency in your project next to the dependency on javax.xml.bind:jaxb-api:

Note that in order to use EclipseLink MOXy, you’ll need to add a jaxb.properties file to your project to specify that you want to use a different JAXB context factory. See Specifying the EclipseLink MOXy Runtime in the documentation for more details.

Using the JAXB tools on JDK 11 or newer

Since JAXB has been completely removed from Java SE 11, the xjc and schemagen tools are also no longer available.

If you want to use these tools from the command line, you can download and install the JAXB reference implementation standalone distribution, or download and install GlassFish, which also includes them.

When you are using Maven then there are different plugins available, such as the jaxb2-maven-plugin and the maven-jaxb2-plugin (note: these are different plugins, despite the similar names).

However, unfortunately both of these plugins seem to currently have issues when you use them on JDK 9 or newer – maybe the real issue is not in the plugins but in the xjc tool itself. This means that for the moment, you’ll have to find a workaround for these issues, or wait until they have been resolved.

Conclusion

If you need to use JAXB on Java SE 9 or newer you need to be aware that there are breaking changes, and you’ll need to update your project to make it work.

I have a course available on Pluralsight about JAXB: Working with XML in Java using JAXB. Take a look at it if you want to learn how to use JAXB!

You may also like...