Java 11 Removed Modules: Java EE, CORBA and JavaFX

Introduction Java 11 is the first Java release which removed whole parts of the platform. The Java EE and CORBA modules were taken out of the JDK (JEP 320), and Oracle stopped bundling JavaFX, Java Web Start and applets with its JDK. Code which used these APIs and compiled fine on Java 8 fails to compile, or fails at runtime, on Java 11. This tutorial explains the modules removed in Java 11 and how to migrate code which uses them. We will first see the errors you get, then why the modules were removed, and lastly what replaces each of them, including the Maven dependencies to add. We will also look at the features which were deprecated in Java 11, such as Nashorn and Pack200.

(Note - The removed APIs are organised as modules, which were introduced in Java 9. To learn about modules, read the Java 9 Modules tutorialClick to read: Java 9 Modules tutorial.) What happens when code uses a removed module A very common example is javax.xml.bind.DatatypeConverter, which many programs used for Base64 and hexadecimal conversion even though it is part of JAXB, an XML binding API. Another is the @PostConstruct annotation from the Common Annotations module. The class below compiles on Java 8, but compiling it for Java 11 gives -
Code which uses removed Java EE APIs
//LegacyCode.java
import javax.annotation.PostConstruct;
import javax.xml.bind.DatatypeConverter;

public class LegacyCode {
  @PostConstruct
  void init() {
    System.out.println("Initialized");
  }

  public static void main(String[] args) {
    byte[] data = "Java 11".getBytes();
    System.out.println(DatatypeConverter.printBase64Binary(data));
    System.out.println(DatatypeConverter.printHexBinary(data));
  }
}
 OUTPUT on compiling the above code
LegacyCode.java:2: error: package javax.annotation does not exist
import javax.annotation.PostConstruct;
                       ^
LegacyCode.java:3: error: package javax.xml.bind does not exist
import javax.xml.bind.DatatypeConverter;
                     ^
LegacyCode.java:6: error: cannot find symbol
  @PostConstruct
   ^
  symbol:   class PostConstruct
  location: class LegacyCode
LegacyCode.java:13: error: cannot find symbol
    System.out.println(DatatypeConverter.printBase64Binary(data));
                       ^
  symbol:   variable DatatypeConverter
  location: class LegacyCode
LegacyCode.java:14: error: cannot find symbol
    System.out.println(DatatypeConverter.printHexBinary(data));
                       ^
  symbol:   variable DatatypeConverter
  location: class LegacyCode
5 errors
  • The compiler reports that the packages javax.xml.bind and javax.annotation do not exist, because the modules which contained them are no longer in the JDK.
  • An application compiled on Java 8 and run on Java 11 fails in a similar way at runtime, with a NoClassDefFoundError or ClassNotFoundException for javax.xml.bind.JAXBContext and the like, as soon as the missing class is used.
Why the modules were removed These APIs were added to Java SE in Java 6, mostly to support web services in the standard JDK. Over time -
  • the same technologies were also developed as standalone projects, as part of Java EE, and the copies in the JDK fell behind those versions,
  • applications which needed them, such as those running on application servers, got them from the server or from libraries anyway, and
  • keeping them in sync made both Java SE and Java EE harder to maintain.
They were deprecated for removal in Java 9, which is why on Java 9 and 10 they were not resolved by default, and needed --add-modules java.xml.bind to be used. Java 11 removed them completely, so that option no longer works either. The removed modules and their replacements
Removed moduleAPIReplacement (Maven groupId:artifactId)
java.xml.bindJAXB - XML bindingjakarta.xml.bind:jakarta.xml.bind-api and org.glassfish.jaxb:jaxb-runtime
java.xml.wsJAX-WS - SOAP web services, SAAJjakarta.xml.ws:jakarta.xml.ws-api and com.sun.xml.ws:jaxws-rt
java.activationJAF - JavaBeans Activation Frameworkjakarta.activation:jakarta.activation-api
java.xml.ws.annotationCommon Annotations - @PostConstruct, @PreDestroy, @Resourcejakarta.annotation:jakarta.annotation-api
java.transactionJTA - a subset of the transaction APIjakarta.transaction:jakarta.transaction-api
java.corbaCORBA, RMI-IIOP, javax.rmiNo standard replacement; the GlassFish ORB (org.glassfish.corba) can be used
The java.se.ee aggregator module, the internal jdk.xml.bind and jdk.xml.ws modules, and the related tools xjc, schemagen, wsgen, wsimport, idlj, orbd, servertool and tnameserv were removed as well. Choosing the version: javax or jakarta When Java EE moved to the Eclipse Foundation and became Jakarta EE, the package names changed from javax.* to jakarta.*. This affects which version of the replacement you add -
  • To keep your existing javax.* imports, use the last versions which still use the old package names - JAXB API 2.3.x, JAX-WS API 2.3.x, Activation API 1.2.x, Annotations API 1.3.x and Transaction API 1.3.x. This is the quickest way to get old code compiling on Java 11.
  • For new code, or if you are moving to Jakarta EE 9 or later (for example Spring Boot 3), use the newer versions, and change the imports from javax.xml.bind to jakarta.xml.bind, and so on.
For example, to keep using javax.xml.bind with Maven, add the following dependencies -
Maven dependencies for JAXB with the javax package names
<dependency>
  <groupId>jakarta.xml.bind</groupId>
  <artifactId>jakarta.xml.bind-api</artifactId>
  <version>2.3.3</version>
</dependency>
<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
  <version>2.3.3</version>
  <scope>runtime</scope>
</dependency>
Both the API and an implementation (the runtime) are needed. In the JDK both were included, which is why only one module had to be added on Java 9 and 10.
Replacing DatatypeConverter without a dependency If DatatypeConverter was the only reason a program used JAXB, a dependency is not needed at all. java.util.Base64 has been part of Java since Java 8, and hexadecimal conversion is only a few lines of code -
Base64 and hex without JAXB
//Base64Replacement.java
import java.util.Base64;

public class Base64Replacement {
  static String toHex(byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for (byte b : bytes) {
      sb.append(String.format("%02X", b));
    }
    return sb.toString();
  }

  public static void main(String[] args) {
    byte[] data = "Java 11".getBytes();
    String base64 = Base64.getEncoder().encodeToString(data);
    System.out.println(base64);
    System.out.println(new String(Base64.getDecoder().decode(base64)));
    System.out.println(toHex(data));
  }
}
 OUTPUT of the above code
SmF2YSAxMQ==
Java 11
4A617661203131
Note - Java 17 added java.util.HexFormat, so on Java 17 and later HexFormat.of().withUpperCase().formatHex(data) replaces the toHex() method above. Finding the removed APIs in your code The jdeps tool, which comes with the JDK, lists the packages a JAR or class directory depends on. Running it with the --jdk-internals option, or reading its regular output for javax.xml.bind, javax.xml.ws, javax.annotation and org.omg, shows which removed APIs your application and its libraries use. Remember to check your libraries too - older versions of many libraries use JAXB internally, and upgrading the library is often the fix.
jdeps --multi-release 11 -summary -recursive --class-path "lib/*" myapp.jar
JavaFX, Java Web Start and applets
  • JavaFX - Oracle JDK 8 included JavaFX, but from Java 11 it is no longer part of the JDK. It is developed as the separate open source project OpenJFX, and added like any other library - for example with the org.openjfx:javafx-controls Maven dependency and the javafx-maven-plugin. Some JDK distributions also offer builds with JavaFX included.
  • Java Web Start and applets - Oracle JDK 11 no longer includes Java Web Start or the browser plugin, so applets and JNLP applications cannot be run with it. Applets had been deprecated in Java 9Click to read: deprecated in Java 9. The usual replacement is to package the application as a self-contained desktop application, using a custom runtime built with jlink. (The jpackage tool for this was added later, in Java 14.)
Deprecated in Java 11 Java 11 also deprecated two features for removal in a later release -
  • The Nashorn JavaScript engine (JEP 335) - Nashorn, added in Java 8 to run JavaScript from Java, prints a deprecation warning from Java 11 and was removed in Java 15. It is now available as a standalone library, org.openjdk.nashorn:nashorn-core, and GraalJS is another alternative.
  • Pack200 (JEP 336) - the Pack200 compression format for JAR files, its pack200 and unpack200 tools, and the java.util.jar.Pack200 API were deprecated, and were removed in Java 14.
Summary In this tutorial we saw that Java 11 removed the Java EE and CORBA modules from the JDK, and the compiler errors this causes for code which uses JAXB, JAX-WS, the Common Annotations and the other removed APIs. We saw why they were removed, and which libraries replace each of them, along with the choice between the javax and jakarta package names. We replaced DatatypeConverter with java.util.Base64, and saw how jdeps finds the removed APIs in an application. Lastly, we looked at JavaFX, Java Web Start and applets, and at the deprecation of Nashorn and Pack200. This completes the Java 11 series - to see all the features of the release in one place, go back to the overview of new features in Java 11Click to read tutorial: Overview of New Features in Java 11.