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
usecom.sun.xml.bind:jaxb-impl:2.3.6
. Ignore the 3.0.0 and later releases. Add an explicit dependency onjavax.xml.bind:jaxb-api:2.3.1
so that you have a package providing thejavax.xml.bind
API - For
jakarta.xml.bind
use the latestorg.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:
- You can set any Java 9+ only options using the
JDK_JAVA_OPTIONS
environment variable. This environment variable is automatically read by thejava
launcher for Java 9+. - 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 propertycom.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
Annotation @Transactional. How to Rollback
Transform Java Future into a Completablefuture
Comparing Strings by Their Alphabetical Order
Java.Nio.File.Path for a Classpath Resource
How to Get the Current Date and Time of Your Timezone in Java
Why Isn't a Qualified Static Final Variable Allowed in a Static Initialization Block
Java, How to Get Current Index/Key in "For Each" Loop
How to Do If-Else in Thymeleaf
Get a Node's Inner Xml as String in Java Dom
What Does Class<> Mean in Java
What Does the Registernatives() Method Do
Spring Configure @Responsebody JSON Format
Are There Inline Functions in Java
What Package Naming Convention Do You Use for Personal/Hobby Projects in Java
Check Line for Unprintable Characters While Reading Text File