Replacements For Deprecated Jpms Modules With Java Ee APIs

Replacements for deprecated JPMS modules with Java EE APIs

Instead of using the deprecated Java EE modules, use the following artifacts.

JAF (java.activation)

JavaBeans Activation Framework (now Jakarta Activation) is a standalone technology (available on Maven Central):

<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
<version>1.2.2</version>
</dependency>

(Source)

CORBA (java.corba)

From JEP 320:

There will not be a standalone version of CORBA unless third parties take over maintenance of the CORBA APIs, ORB implementation, CosNaming provider, etc. Third party maintenance is possible because the Java SE Platform endorses independent implementations of CORBA. In contrast, the API for RMI-IIOP is defined and implemented solely within Java SE. There will not be a standalone version of RMI-IIOP unless a dedicated JSR is started to maintain it, or stewardship of the API is taken over by the Eclipse Foundation (the transition of stewardship of Java EE from the JCP to the Eclipse Foundation includes GlassFish and its implementation of CORBA and RMI-IIOP).

JTA (java.transaction)

Stand alone version:

<dependency>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
<version>1.3.3</version>
</dependency>

(Source)

JAXB (java.xml.bind)

Since Java EE was rebranded to Jakarta EE, JAXB is now provided by new artifacts:

<!-- API -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>

<!-- Runtime -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
<scope>runtime</scope>
</dependency>

<!-- Alternative runtime -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
<scope>runtime</scope>
</dependency>

JAXB Reference Implementation page.

The alternative runtime was brought up by Abhijit Sarkar.

schemagen and xjc can be downloaded from there too as part of a standalone JAXB distribution.

See also linked answer.

JAX-WS (java.xml.ws)

Reference implementation:

<!-- API -->
<dependency>
<groupId>jakarta.xml.ws</groupId>
<artifactId>jakarta.xml.ws-api</artifactId>
<version>2.3.3</version>
</dependency>

<!-- Runtime -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>

Standalone distribution download (contains wsgen and wsimport).

Common Annotations (java.xml.ws.annotation)

Java Commons Annotations (available on Maven Central):

<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>1.3.5</version>
</dependency>

(Source)

Which criterias to consider when replacing the Java EE modules removed from JDK?

It's not really "choose between Jakarta or the Sun reference implementation". Jakarta is now what used to be called Java EE (Oracle handed it over to the Eclipse Foundation and it got a new name). The standards are developed under the Jakarta project, and for each standard (such as JAX-WS) there is a reference implementation.

Other vendors might implement the standard independently. The choice is not between "Jakarta or the Sun reference implementation", but between the reference implementation and an implementation by another vendor.

For example, look at JAXB (the Java API for XML Binding). There is a reference implementation and there is also MOXy, which is a separate implementation that has some extra, non-standard features.

Here is the Jakarta page about JAX-WS, which lists two implementations: the reference implementation which has Maven coordinates jakarta.xml.ws:jakarta.xml.ws-api:jar:2.3.3, and Eclipse Metro which is an alternative implementation.

To choose, you need to look at the features of both and decide what you want to use.

Note that if you are running your software on a Java EE or Jakarta EE application server, there might already be an implementation of JAX-WS included with it.

Write your program against the JAX-WS API, and not against a particular implementation, unless you need to use non-standard extensions of a particular implementation (but that will, of course, make it hard to switch to a different implementation later).

Is there a JMS module for Java 9 JPMS?

There is not a JPMS module for the Java EE JMS API, but you might be able to use it as an automatic module even if it doesn't have the Automatic-Module-Name in its manifest.

There won't ever be a proper JPMS module for the Java EE JMS API, but there may someday be a JPMS module for the Jakarta EE version of the JMS API (Jakarta EE is the successor to Java EE).

Selectively using third-party implementation for deprecated JavaEE modules

Is there a way to produce a jar file that will use the third party
implementations on JDK9+ and the endorsed ones on JDK8?

Unfortunately, no. When distributing a library via jar file, you cannot control how other jars and libraries will be listed in the classpath. This makes class loading non-deterministic for you. What that means for your situation is that if the aforementioned libraries are included in the classpath in a JDK8 environment, there is no way to determine or control which version of the classes get loaded.

Also, in case it's not possible to use the endorsed implementations on
JDK 8, is there a way to reliably test that using the third party
implementations does not introduce any regressions?

As the author, it would be up to you to execute tests across the different runtime environments to check for regressions.

Should I publish two different jars, one with the Java EE third party
implementations included, for JDK9+ and one without for JDK8?

This is a perfectly reasonable solution which others have used before as well. Take for example the sqlserver jdbc jars, which have different versions based on jre: https://docs.microsoft.com/en-us/sql/connect/jdbc/using-the-jdbc-driver?view=sql-server-2017
For the case described here, the JDK9+ version of the jar could declare the additional dependencies you mentioned in the question, whereas the JDK8 version would not.

One other option would be to have a single jar and to declare the dependecies you mentioned as provided. This would signal to the consumer that the runtime environment must include the classes in the declared dependencies. Some documentation would be called for to direct the consumer of the library as to when to they must explicitly add the jars declared as provided to their classpath.

IMHO, the clearest solution is two jars with a reference to the JRE version in the jar name and differing dependencies. It requires very little documentation (which most dont look at anyway). And it allows you to make changes in your library more freely.

Java 11 package javax.xml.bind does not exist

According to the release-notes, Java 11 removed the Java EE modules:

java.xml.bind (JAXB) - REMOVED
  • Java 8 - OK
  • Java 9 - DEPRECATED
  • Java 10 - DEPRECATED
  • Java 11 -
    REMOVED

See JEP 320 for more info.

You can fix the issue by using alternate versions of the Java EE technologies. Simply add Maven dependencies that contain the classes you need:

<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>

Jakarta EE 8 update (Mar 2020)

Instead of using old JAXB modules you can fix the issue by using Jakarta XML Binding from Jakarta EE 8:

<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
<scope>runtime</scope>
</dependency>

Jakarta EE 9 update (Nov 2020)

Use latest release of Jakarta XML Binding 3.0:

  • Jakarta EE 9 API jakarta.xml.bind-api
  • compatible implementation jaxb-impl
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>3.0.0</version>
<scope>runtime</scope>
</dependency>

Note: Jakarta EE 9 adopts new API package namespace jakarta.xml.bind.*, so update import statements:

javax.xml.bind -> jakarta.xml.bind

Jakarta EE 10 update (Jun 2022)

Use latest release of Jakarta XML Binding 4.0 (requires Java SE 11 or newer):

  • Jakarta EE 10 API jakarta.xml.bind-api
  • compatible implementation jaxb-impl
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>4.0.0</version>
<scope>runtime</scope>
</dependency>

Java 10: Replacement for java.xml.ws conflict

Just use Java 11 :) There is no javax.xml.ws module there, so no conflict.

As for Java 10, the easiest workaround is to change the scope of jaxws-ri to runtime:

<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.0</version>
<scope>runtime</scope>
</dependency>


Related Topics



Leave a reply



Submit