Which Artifacts Should I Use for Jaxb Ri in My Maven Project

Which artifacts should I use for JAXB RI in my Maven project?

After clarification with Oracle, the following artifacts should be used:

Runtime

If you want to unmarshal XML to Java objects or marshal Java objects as XML:

<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>...</version>
</dependency>

Schema compiler (XJC)

If you have an XML Schema and want to generate the Java code out of it:

<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>...</version>
</dependency>

Schema generator (JXC/schemagen)

If you have Java classes with JAXB annotations and want to generate a XML Schema based on them:

<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-jxc</artifactId>
<version>...</version>
</dependency>

The two latter artifacts (org.glassfish.jaxb:jaxb-xjc and org.glassfish.jaxb:jaxb-jxc) are wrapped by Maven plugins so you normally would not need them in the runtime.

Eclipse usage

If your Maven projects somehow don't get the full classpath, turn on debug output and check the Maven console. You might be seeing the following error message there:

[ERROR] 'dependencyManagement.dependencies.dependency.systemPath' for com.sun:tools:jar must specify an absolute path but is ${tools.jar} @

This is due to the following problem:

Maven not picking JAVA_HOME correctly

The solution by @rustyx is to add -vm option to the eclipse.ini:

-vm
<PATH_TO_JDK>\jre\bin\javaw.exe

What is the difference between jaxb-impl and jaxb-runtime?

The only difference between jaxb-impl and jaxb-runtime is packaging: jaxb-impl bundles istack/txw2 inside the jar, whereas jaxb-runtime provides them via separate dependencies.

Version Compatibility and the JakartaEE Migration

I've been trying to make sense of this for the last day, and it's incredibly confusing. Particularly when you're trying to avoid the java.xml.bind to jakarta.xml.bind migration. There's out of date information everywhere and some broken releases in the jaxb-impl 2.3.x release line.

Best I can tell, GlassFish was providing the JAXB reference implementation. It's since moved to EE4J, but releases continue from that project against both sets of coordinates. Appears that com.sun.xml.bind:jaxb-ri is where the latest full bundles are released:

https://github.com/eclipse-ee4j/jaxb-ri/

Having figured out that piece of history, the real mess is that none of the artifacts reflect the javax.xml.bind to jakarta.xml.bind move in their artifact coordinates, only in the versions. This means if you're in ecosystem where you need both to exist, you're going to have a bad time.

For instance, the 2.3.3 release changed from depending on javax.xml.bind:jaxb-api to jakarta.xml.bind:jakarta.xml.bind-api because at 2.x, the jakarta artifacts provide the javax.xml.bind packages. At version 3.0.0 it provides jakarta.xml.bind.

The implementations are the same at 3.0.0 which means while the earlier versions could happily exist at runtime, you have no way of resolving them both in build tools and conflict resolution is going to break legacy uses of javax.xml.bind APIs.

Allow javax.xml.bind and jakarta.xml.bind to coexist

For projects that need both APIs to coexist without migrating the legacy code:

  • For javax.xml.bind use com.sun.xml.bind:jaxb-impl:2.3.6. Ignore the 3.0.0 and later releases. Add an explicit dependency on javax.xml.bind:jaxb-api:2.3.1 so that you have a package providing the javax.xml.bind API
  • For jakarta.xml.bind use the latest org.glassfish.jaxb:jaxb-runtime. Ignore the releases earlier than 3.0.0

Runtime compatibility with jakarta.xml.bind

Use the tomcat-jakartaee-migration tool to rewrite classes to use the new API at build time or at deployment time. If you use Gradle, you could use this with artifact transforms.

Migrate to jakarta.xml.bind

You can use either of the coordinates for the runtime based on your preferences for packaging:

  • com.sun.xml.bind:jaxb-impl:4.0.0
  • org.glassfish.jaxb:jaxb-runtime:4.0.0

Both depend on jakarta.xml.bind:jakarta.xml.bind-api with the jakarta.xml.bind package namespace.

Include JAXB using Maven

I just ran into this issue with jaxb also; goodness do I love Maven (not). Here's how I resolved the problem.

Add the central repo


<repository>
<id>central</id>
<url>http://repo.maven.apache.org/maven2/</url>
</repository>

Modify the version of the api and impl


<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.5-b10</version>
</dependency>

Could not find artifact sun-jaxb:jaxb-api:jar:2.2 in central

Why the error is saying that it can not find the artifact and is there a way to solve this issue?

Because the dependency in the POM files is incorrect. I checked, and there are no official dependencies for "sun-jaxb" in Maven Central.

The correct Maven dependency for the JAXB apis in Java 8 is

      <dependency>                                                          
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.8</version>
<scope>provided</scope>
</dependency>

as described in "https://stackoverflow.com/questions/63608553". I checked and the artifact is there, as are older and newer versions.

So a good solution would be to update all of the POM dependencies.


Now I presume that you are trying to build was building correctly before you started porting it. (Did you check?) If it was, then it must having been getting the "sun-jaxb:jaxb-api:jar:2.2" dependency from ... somewhere:

  • It might have been in Maven Central "unofficially" and removed as a result of a clean-up
  • You (or the previous maintainer) might have installed it directly into the local repo on your build box.
  • You might have been getting it from another repo; e.g. a corporate Maven repo where someone has previously uploaded it.

It would be a good idea to figure out how it worked before.

How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

The JAXB APIs are considered to be Java EE APIs and therefore are no longer contained on the default classpath in Java SE 9. In Java 11, they are completely removed from the JDK.

Java 9 introduces the concepts of modules, and by default, the java.se aggregate module is available on the classpath (or rather, module-path). As the name implies, the java.se aggregate module does not include the Java EE APIs that have been traditionally bundled with Java 6/7/8.

Fortunately, these Java EE APIs that were provided in JDK 6/7/8 are still in the JDK, but they just aren't on the classpath by default. The extra Java EE APIs are provided in the following modules:

java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation

Quick and dirty solution: (JDK 9/10 only)

To make the JAXB APIs available at runtime, specify the following command-line option:

--add-modules java.xml.bind

But I still need this to work with Java 8!!!

If you try specifying --add-modules with an older JDK, it will blow up because it's an unrecognized option. I suggest one of two options:

  1. You can set any Java 9+ only options using the JDK_JAVA_OPTIONS environment variable. This environment variable is automatically read by the java launcher for Java 9+.
  2. You can add the -XX:+IgnoreUnrecognizedVMOptions to make the JVM silently ignore unrecognized options, instead of blowing up. But beware! Any other command-line arguments you use will no longer be validated for you by the JVM. This option works with Oracle/OpenJDK as well as IBM JDK (as of JDK 8sr4).

Alternate quick solution: (JDK 9/10 only)

Note that you can make all of the above Java EE modules available at run time by specifying the --add-modules java.se.ee option. The java.se.ee module is an aggregate module that includes java.se.ee as well as the above Java EE API modules. Note, this doesn't work on Java 11 because java.se.ee was removed in Java 11.



Proper long-term solution: (JDK 9 and beyond)

The Java EE API modules listed above are all marked @Deprecated(forRemoval=true) because they are scheduled for removal in Java 11. So the --add-module approach will no longer work in Java 11 out-of-the-box.

What you will need to do in Java 11 and forward is include your own copy of the Java EE APIs on the classpath or module path. For example, you can add the JAX-B APIs as a Maven dependency like this:

<!-- API, java.xml.bind module -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>

<!-- Runtime, com.sun.xml.bind module -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>

See the JAXB Reference Implementation page for more details on JAXB.

For full details on Java modularity, see JEP 261: Module System

As of July 2022, the latest version of the bind-api and jaxb-runtime is 4.0.0. So you can also use

    <version>4.0.0</version>

...within those dependency clauses. But if you do so, the package names have changed from javax.xml.bind... to jakarta.xml.bind.... You will need to modify your source code to use these later versions of the JARs.

For Gradle or Android Studio developer: (JDK 9 and beyond)

Add the following dependencies to your build.gradle file:

dependencies {
// JAX-B dependencies for JDK 9+
implementation "jakarta.xml.bind:jakarta.xml.bind-api:2.3.2"
implementation "org.glassfish.jaxb:jaxb-runtime:2.3.2"
}

Maven fails to download dependencies

first thing to realize is that the error is about

Cannot find parent: com.sun.xml.bind:jaxb-bom-ext for project: com.sun.xml.bind.mvn:jaxb-parent:pom:null

So I'd intentionally say, even if I dont know what that bubblegateway is, that this POM is not located in your local repository. To find your local repository in eclipse for example watch the maven settings, there should be a path specified.

In this repository folders are like names in your errormessage. So the folder structure should look like

com/sun/xml/bind/2.3.1

Behind the ":" follows the artifactId. This is the significant name part of your .pom, or .jar file then.

So the file he is looking for should be: jaxb-bom-ext.pom

I'd bet he doesn't find it. Take a look yourself, I may be mistaken.

Now how to get it:

from the specified remote repositories:
central (http://repo1.maven.org/maven2),
bubbleGateway (http://example.com:8081/repository/public/)

He is looking your predefined repositories, I suppose you did setup them in a maven settings file, but you can set them elsewhere aswell.
Point is, calling http://repo1.maven.org/maven2 wont help anymore because it moved some time ago to the secure site https://repo1.maven.org/maven2 .

Check it out in your browser, the first one will give you a 501. And the latter should give you a running repository where you can find your pom.

So basically all you have to do is, if I'm not mistaken, find the place where you define your repositories, and add the "s" ;)

Good luck.

Why has AnnotationReader been removed from JAXB reference implementation?

JAXB artifacts were restructured in 2.2.11 so a few classes were moved between jaxb-runtime and jaxb-core. AnnotationReader is not the only one. The main reason is (probably) the mavenisation which required rearranging a few classes due to dependency structure.

Unfortunately the old artifacts com.sun.xml.bind:* has a bit wrong dependency structure so if you just used jaxb-impl before you'd also need jaxb-core. If this was your problem you should move to the new org.glassfish.jaxb:* artifacts as they have the right structure. org.glassfish.jaxb:jaxb-core is a dependency of org.glassfish.jaxb:jaxb-runtime which replaces the old org.glassfish.jaxb:jaxb-impl.

See also:

Which artifacts should I use for JAXB RI in my Maven project?

Proper fix for Java 10 complaining about illegal reflection access by jaxb-impl 2.3.0?

jaxb-ri runtime uses ClassLoader#defineClass / Unsafe#defineClass to do some bytecode modification in runtime to optimize performance. ClassLoader#defineClass is tried first which causes the warning.

This legacy optimization is removed completely in jaxb-ri master (after 2.3.0, not released yet).

To disable this optimization for 2.3.0, set system property
com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize.

After next jaxb-ri release updating to newest version will remove the warning.
jaxb-core artifact will be discontinued in favor for JPMS support. Correct pom will look like:

<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.4.0</version>
</dependency>

If you wish to try early, you can pick latest promoted build from:
https://maven.java.net/content/groups/promoted/org/glassfish/jaxb/jaxb-runtime/



Related Topics



Leave a reply



Submit