我有一些使用JAXB API类的代码,这些类作为Java 6/7/8中JDK的一部分提供。当我使用Java 9运行相同的代码时,在运行时出现错误,指示找不到JAXB类。
自Java 6以来,JAXB类已经作为JDK的一部分提供了,那么Java 9为什么不能再找到这些类?
我有一些使用JAXB API类的代码,这些类作为Java 6/7/8中JDK的一部分提供。当我使用Java 9运行相同的代码时,在运行时出现错误,指示找不到JAXB类。
自Java 6以来,JAXB类已经作为JDK的一部分提供了,那么Java 9为什么不能再找到这些类?
Answers:
JAXB API被视为Java EE API,因此不再包含在Java SE 9的默认类路径中。在Java 11中,它们已从JDK中完全删除。
Java 9引入了模块的概念,默认情况下,java.se
聚合模块可在类路径(或更确切地说,模块路径)上使用。正如其名称所暗示的,java.se
汇聚模块并没有包括那些与Java 6/7/8传统上捆绑了Java EE的API。
幸运的是,JDK 6/7/8中提供的这些Java EE API仍在JDK中,但是默认情况下它们不在类路径中。以下模块提供了额外的Java EE API:
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
快速而肮脏的解决方案:(仅JDK 9/10)
要使JAXB API在运行时可用,请指定以下命令行选项:
--add-modules java.xml.bind
但是我仍然需要这个才能与Java 8一起使用!!!
如果尝试--add-modules
使用较旧的JDK进行指定,则该选项会崩溃,因为它是无法识别的选项。我建议两种选择之一:
JDK_JAVA_OPTIONS
环境变量设置任何仅Java 9+的选项。Java 9+ 的启动器会自动读取此环境变量java
。-XX:+IgnoreUnrecognizedVMOptions
,使JVM静默忽略无法识别的选项,而不是崩溃。但是要当心!JVM将不再为您验证您使用的任何其他命令行参数。该选项与Oracle / OpenJDK以及IBM JDK(自JDK 8sr4起)一起使用。备用快速解决方案:(仅JDK 9/10)
请注意,您可以通过指定--add-modules java.se.ee
选项在运行时使上述所有Java EE模块可用。该java.se.ee
模块是一个聚合模块,其中包括java.se.ee
上述Java EE API模块。请注意,这在Java 11上不起作用,因为java.se.ee
已在Java 11中删除。
正确的长期解决方案:(JDK 9和更高版本)
上面列出的Java EE API模块均已标记,@Deprecated(forRemoval=true)
因为它们计划在Java 11中删除。因此,该--add-module
方法将无法在Java 11中直接使用。
在Java 11及更高版本中,您需要做的是在类路径或模块路径上包含您自己的Java EE API副本。例如,您可以像这样将JAX-B API添加为Maven依赖项:
<!-- 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>
有关JAXB的更多详细信息,请参见JAXB参考实现页面。
有关Java模块化的完整详细信息,请参见JEP 261:模块系统。
对于Gradle或Android Studio开发人员:(JDK 9及更高版本)
将以下依赖项添加到build.gradle
文件中:
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"
}
javax.xml.bind
和其他的JavaEE类计划删除在Java中11,每JEP-320。
java.se.ee
模块已删除,因此该--add-modules
解决方案不再起作用。请使用推荐的解决方案:将JAXB添加为单独的依赖项。
在我的情况下(春季启动胖子),我只是将以下内容添加到pom.xml中。
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
testCompile('javax.xml.bind:jaxb-api')
对我有用。
<scope>runtime</scope>
这种情况下使用
在最近的JDK 9.0.1中,这些解决方案都对我不起作用。
我发现此依赖关系列表足以正常运行,因此您无需显式指定--add-module
(尽管它是在这些依赖关系的pom内指定的)。您唯一需要的是指定此依赖性列表:
<dependencies>
<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-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
pom.xml
Maven配置的文件。如果您不知道那是什么,那么最好从开始做起
<dependency> <groupId>javax.activation</groupId> <artifactId>javax.activation-api</artifactId> <version>1.2.0</version> </dependency>
最后一个依赖项。
这为我工作:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.0</version>
</dependency>
正如@Jasper所建议的那样,为了避免依赖整个EclipseLink库,您还可以仅依赖EclipseLink MOXy:
马文
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
<version>2.7.3</version>
</dependency>
摇篮
compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.moxy', version: '2.7.3'
作为我的Java 8应用程序的依赖项,该应用程序生成一个* .jar,它可以由JRE 8或JRE 9运行,而无需其他参数。
另外,这需要在使用JAXB API之前的某处执行:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
到目前为止,效果很好,是一种解决方法。虽然看起来不是一个完美的解决方案...
org.eclipse.persistence:eclipselink
刚拿到JAXB的API是一个非常重量级的依赖关系,除非你已经在使用的EclipseLink?
-XX:+IgnoreUnrecognizedVMOptions
命令行选项(详细说明更新了我的答案)
org.eclipse.persistence
,artifactId org.eclipse.persistence.moxy
。
您需要在构建中添加两个依赖项
作为一种实现,我选择使用glassfish的参考实现来摆脱旧的com.sun类/库。因此,我添加了我的Maven版本
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>
请注意,从2.3.1版开始,您不再需要添加javax.activation。(参见https://github.com/eclipse-ee4j/jaxb-ri/issues/1222)
这是因为如果您使用的是jdk 9,则是Java版本,或者只是将其添加到pom中
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
为了解决这个问题,我在项目中导入了一些JAR文件:
http://search.maven.org/remotecontent?filepath=javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar
http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-core/2.3.0/jaxb-core-2.3.0.jar
http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar
com.sun.xml.bind
工件是旧的,仅提供用于向后兼容。org.glassfish.jaxb
如其他一些答案中所述,您应该改用等效的工件。
在编译以及运行时,添加开关 --add-modules java.xml.bind
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
JDK 9
您也可以在以下网址找到有关这些模块的详细介绍:https :
//www.youtube.com/watch?v=KZfbRuvv5qc
这对我有用。仅添加jaxb-api是不够的。
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
com.sun.xml.bind
工件是旧的,仅提供用于向后兼容。org.glassfish.jaxb
如其他一些答案中所述,您应该改用等效的工件。
转到Build.gradle并为Java 9或Java 10添加以下依赖项。
sourceCompatibility = 10 // You can also decrease your souce compatibility to 1.8
//java 9+ does not have Jax B Dependents
compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
compile group: 'com.sun.xml.bind', name: 'jaxb-core', version: '2.3.0'
compile group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.3.0'
compile group: 'javax.activation', name: 'activation', version: '1.1.1'
您可以使用--add-modules=java.xml.bind
JVM选项将xml绑定模块添加到JVM运行时环境。
例如: java --add-modules=java.xml.bind XmlTestClass
2019年4月更新
JAXB版本的Changelong位于https://javaee.github.io/jaxb-v2/doc/user-guide/ch02.html
摘录:
4.1. Changes between 2.3.0.1 and 2.4.0
JAXB RI is now JPMS modularized:
All modules have native module descriptor.
Removed jaxb-core module, which caused split package issue on JPMS.
RI binary bundle now has single jar per dependency instead of shaded fat jars.
Removed runtime class weaving optimization.
4.2. Changes between 2.3.0 and 2.3.0.1
Removed legacy technology dependencies:
com.sun.xml.bind:jaxb1-impl
net.java.dev.msv:msv-core
net.java.dev.msv:xsdlib
com.sun.xml.bind.jaxb:isorelax
4.3. Changes between 2.2.11 and 2.3.0
Adopt Java SE 9:
JAXB api can now be loaded as a module.
JAXB RI is able to run on Java SE 9 from the classpath.
Addes support for java.util.ServiceLoader mechanism.
Security fixes
权威链接位于https://github.com/eclipse-ee4j/jaxb-ri#maven-artifacts
JAXB工件的Maven坐标
jakarta.xml.bind:jakarta.xml.bind-api:JAXB的API类。需要针对JAXB进行编译。
org.glassfish.jaxb:jaxb-runtime:JAXB的实现,运行时用于将Java对象与xml进行序列化和反序列化。
JAXB胖罐捆绑包:
com.sun.xml.bind:jaxb-impl:JAXB运行时胖子。
与org.glassfish.jaxb工件相反,这些jars包含所有依赖项类。这些工件不包含JPMS模块描述符。在Maven项目中,应该使用org.glassfish.jaxb工件代替。
org.glassfish.jaxb:jaxb运行时:jar:2.3.2引入:
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:2.3.2:compile
[INFO] | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile
[INFO] | +- org.glassfish.jaxb:txw2:jar:2.3.2:compile
[INFO] | +- com.sun.istack:istack-commons-runtime:jar:3.0.8:compile
[INFO] | +- org.jvnet.staxex:stax-ex:jar:1.8.1:compile
[INFO] | +- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.16:compile
[INFO] | \- jakarta.activation:jakarta.activation-api:jar:1.2.1:compile
原始答案
下面我要在我的Maven项目使用哪些文物为JAXB RI? 在Maven中,您可以使用如下配置文件:
<profile>
<id>java-9</id>
<activation>
<jdk>9</jdk>
</activation>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</profile>
依赖关系树显示:
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:2.3.0:compile
[INFO] | +- org.glassfish.jaxb:jaxb-core:jar:2.3.0:compile
[INFO] | | +- javax.xml.bind:jaxb-api:jar:2.3.0:compile
[INFO] | | +- org.glassfish.jaxb:txw2:jar:2.3.0:compile
[INFO] | | \- com.sun.istack:istack-commons-runtime:jar:3.0.5:compile
[INFO] | +- org.jvnet.staxex:stax-ex:jar:1.7.8:compile
[INFO] | \- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.13:compile
[INFO] \- javax.activation:activation:jar:1.1.1:compile
要在Eclipse中使用它,请说Oxygen.3a Release(4.7.3a)或更高版本,按Ctrl-Alt-P,或右键单击项目Maven,然后选择配置文件。
javax.xml.bind
> 的依赖jaxb-api
实际上是多余的。Glassfish依赖关系确实如此。我只是尝试过,它确实有效。
对于Java Web Start执行,我们可以使用Andy Guibert的建议,如下所示:
<j2se version="1.6+"
java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/>
请注意--add-modules中的额外“ =”。请参阅此OpenJDK票证或Java平台标准版Oracle JDK 9迁移指南的 “了解运行时访问警告”中的最后一个注释。
由于JavaEE现在受https://jakarta.ee/管辖,因此自2.3.2起的新Maven坐标为:
https://eclipse-ee4j.github.io/jaxb-ri/#maven-artifacts
第一个发行的jaxb.version是2.3.2。
<properties>
<jaxb.version>2.3.2</jaxb.version>
</properties>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${jaxb.version}</version>
</dependency>
我遵循此URL,以下设置确实对我有所帮助。我在Macbook Pro中将Java 10与STS IDE一起使用。它像一种魅力。
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
这解决了我在Java 12上运行Apache Camel 2.24.1的依赖项的问题:
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0.1</version>
</dependency>
我2.0.5.RELEASE
在Java 11上使用Spring Boot遇到了相同的问题。
javax.xml.bind:jaxb-api:2.3.0
单独添加并不能解决问题。我还必须将Spring Boot更新到最新的Milestone 2.1.0.M2
,所以我认为这将在下一个正式版本中得到解决。
使用JDK 9+时,需要添加JAX-B依赖项。对于Android Studio用户,您需要将此添加到您build.gradle
的dependencies {}
块中:
// Add missing dependencies for JDK 9+
if (JavaVersion.current().ordinal() >= JavaVersion.VERSION_1_9.ordinal()) {
// If you're using @AutoValue or any libs that requires javax.annotation (like Dagger)
compileOnly 'com.github.pengrad:jdk9-deps:1.0'
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
// If you're using Kotlin
kapt "com.sun.xml.bind:jaxb-core:2.3.0.1"
kapt "javax.xml.bind:jaxb-api:2.3.1"
kapt "com.sun.xml.bind:jaxb-impl:2.3.2"
// If you're using Java
annotationProcessor "com.sun.xml.bind:jaxb-core:2.3.0.1"
annotationProcessor "javax.xml.bind:jaxb-api:2.3.1"
testAnnotationProcessor "com.sun.xml.bind:jaxb-core:2.3.0.1"
testAnnotationProcessor "javax.xml.bind:jaxb-api:2.3.1"
}
我还使用Java 11和Java跨类NotNotFoundException:javax.xml.bind.DatatypeConverter
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
我在添加javax.xml.bind:jaxb-api或spring boot jakarta.xml.bind-api的过程中尝试了所有这些事情。.我在jjwt版本0.10.0中发现了修复的提示..但最重要的是,jjwt软件包是现在分裂!
因此,请检查此参考:https : //github.com/jwtk/jjwt/issues/510
简单来说,如果您使用
Java11和jjwt 0.9.x,您会遇到ClassNotFoundException:javax.xml.bind.DatatypeConverter问题,
去做
jjwt版本0.11.x,但使用拆分的软件包:https : //github.com/jwtk/jjwt#install
您将无法找到jjwt依赖项的更高版本,因为它们拆分了软件包。
干杯。
不是一个答案,而是一个附录:我得到了,因为groovysh
如果JAVA_HOME指向Java 9安装(java version "9.0.1"
准确地说),运行(Groovy 2.4.13 )失败了:
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:107)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:129)
Caused by: java.lang.NoClassDefFoundError: Unable to load class groovy.xml.jaxb.JaxbGroovyMethods due to missing dependency javax/xml/bind/JAXBContext
at org.codehaus.groovy.vmplugin.v5.Java5.configureClassNode(Java5.java:400)
at org.codehaus.groovy.ast.ClassNode.lazyClassInit(ClassNode.java:277)
at org.codehaus.groovy.ast.ClassNode.getMethods(ClassNode.java:397)
...
..
.
..
...
at org.codehaus.groovy.tools.shell.Groovysh.<init>(Groovysh.groovy:135)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232)
at org.codehaus.groovy.tools.shell.Main.<init>(Main.groovy:66)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232)
at org.codehaus.groovy.tools.shell.Main.main(Main.groovy:163)
... 6 more
解决方案是:
转到github.io 上的JAXB项目(“ JAXB已获得双重许可-具有类路径异常的CDDL 1.1和GPL 2.0”)
下载 jaxb-ri-2.3.0.zip
无论您将Java基础结构文件放在何处,都要解压缩(在我的情况下是/usr/local/java/jaxb-ri/
)。可能存在其他解决方案(也许通过SDKMAN,我不知道)
确保lib子目录中的jar放在上CLASSPATH
。我通过在bash启动时启动的脚本来完成此操作,该脚本称为/etc/profile.d/java.sh
,在其中添加了(在许多其他行中)以下循环:
包装成一个功能...
function extend_qzminynshg {
local BASE="/usr/local/java"
for LIB in jaxb-api.jar jaxb-core.jar jaxb-impl.jar jaxb-jxc.jar jaxb-xjc.jar; do
local FQLIB="$BASE/jaxb-ri/lib/$LIB"
if [[ -f $FQLIB ]]; then
export CLASSPATH=$FQLIB:$CLASSPATH
fi
done
}
extend_qzminynshg; unset extend_qzminynshg
而且有效!
您只需要1个依赖项:
dependencies {
implementation ("jakarta.xml.bind:jakarta.xml.bind-api:2.3.2")
好的,我遇到过同样的问题,但是我使用的是Java 8,并且一直出现此错误,因此我尝试了大多数解决方案。但是事实证明,即使我将全局Java版本设置为8后,我的专家仍然指向Java 9。
对于任何可能遇到这种问题的人,请查看如何修复Maven以使用默认Java。
旧答案“通过切换到amazoncorretto解决了问题”新闻答案:我使用了最新的corretto,但与jdk 1.8相似。所以无论如何我们都需要手动添加依赖项
amazoncorretto:latest
目前提供的是JDK 8,而不是11。许多Docker映像仍基于JDK 8,正是由于JDK 8-> 11
我为Java 8目标编译时需要使用的依赖项版本。在Java 8、11和12 JRE中测试了应用程序。
<!-- replace dependencies that have been removed from JRE's starting with Java v11 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.8</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.8-b01</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.8-b01</version>
</dependency>
<!-- end replace dependencies that have been removed from JRE's starting with Java v11 -->
您需要向Maven添加jaxb依赖关系。glassfish实现版本2.3.2与新的jakarta EE jaxb api版本2.3.2完全兼容。
<!-- API -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>
<!-- Runtime -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>
我的项目升级到Java的11后,我也有类似的问题,那么什么固定它升级到春季启动2.1.1这显然对Java的支持11,这有助于