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
OUTPUT on compiling the above code
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
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
OUTPUT of the above code
Note - Java 17 added
JavaFX, Java Web Start and applets
(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));
}
}
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.bindandjavax.annotationdo 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
NoClassDefFoundErrororClassNotFoundExceptionforjavax.xml.bind.JAXBContextand the like, as soon as the missing class is used.
- 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.
--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 module | API | Replacement (Maven groupId:artifactId) |
|---|---|---|
java.xml.bind | JAXB - XML binding | jakarta.xml.bind:jakarta.xml.bind-api and org.glassfish.jaxb:jaxb-runtime |
java.xml.ws | JAX-WS - SOAP web services, SAAJ | jakarta.xml.ws:jakarta.xml.ws-api and com.sun.xml.ws:jaxws-rt |
java.activation | JAF - JavaBeans Activation Framework | jakarta.activation:jakarta.activation-api |
java.xml.ws.annotation | Common Annotations - @PostConstruct, @PreDestroy, @Resource | jakarta.annotation:jakarta.annotation-api |
java.transaction | JTA - a subset of the transaction API | jakarta.transaction:jakarta.transaction-api |
java.corba | CORBA, RMI-IIOP, javax.rmi | No standard replacement; the GlassFish ORB (org.glassfish.corba) can be used |
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.bindtojakarta.xml.bind, and so on.
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>
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));
}
}
SmF2YSAxMQ== Java 11 4A617661203131
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 - 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-controlsMaven dependency and thejavafx-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. (Thejpackagetool for this was added later, in Java 14.)
- 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
pack200andunpack200tools, and thejava.util.jar.Pack200API were deprecated, and were removed in Java 14.
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.Continue Reading Java 11 Tutorials
Java 11 HTTP Client API Tutorial with ExamplesClick to read tutorial: Java 11 HTTP Client API Tutorial with Examples Overview of New Features in Java 11Click to read tutorial: Overview of New Features in Java 11 Java 11 String Methods: isBlank, lines, strip, repeatClick to read tutorial: Java 11 String Methods: isBlank, lines, strip, repeat Java 11 var in Lambda Parameters with ExamplesClick to read tutorial: Java 11 var in Lambda Parameters with Examples Java 11: Run Single-File Source Code Programs with javaClick to read tutorial: Java 11: Run Single-File Source Code Programs with java Java 11 API Additions: Files.readString, Predicate.notClick to read tutorial: Java 11 API Additions: Files.readString, Predicate.not
Java 11 HTTP Client API Tutorial with ExamplesClick to read tutorial: Java 11 HTTP Client API Tutorial with Examples Overview of New Features in Java 11Click to read tutorial: Overview of New Features in Java 11 Java 11 String Methods: isBlank, lines, strip, repeatClick to read tutorial: Java 11 String Methods: isBlank, lines, strip, repeat Java 11 var in Lambda Parameters with ExamplesClick to read tutorial: Java 11 var in Lambda Parameters with Examples Java 11: Run Single-File Source Code Programs with javaClick to read tutorial: Java 11: Run Single-File Source Code Programs with java Java 11 API Additions: Files.readString, Predicate.notClick to read tutorial: Java 11 API Additions: Files.readString, Predicate.not