如何解决Java 9中的java.lang.NoClassDefFoundError:javax / xml / bind / JAXBException

我有一些使用JAXB API类的代码,它们是作为Java 6/7/8中JDK的一部分提供的。 当我使用Java 9运行相同的代码时,在运行时,我收到错误,指出在运行时无法findJAXB类。

自Java 6以来,JAXB类已经作为JDK的一部分提供,那么Java 9为什么不能再find这些类呢?

JAXB API被认为是Java EE API,因此不再包含在Java SE 9的默认类path中。

Java 9引入了模块的概念,默认情况下, java.se聚合模块在类path(或模块path)上可用。 顾名思义, java.se聚合模块不包含传统上与Java 6/7/8捆绑在一起的Java EE API。

幸运的是,JDK 6/7/8中提供的这些Java EE API仍然在JDK中,但默认情况下它们不在类path中。 额外的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 

快速解决scheme
要使JAXB API在运行时可用,请指定以下命令行选项:
--add-modules java.xml.bind

但我仍然需要这个与Java 8一起工作!
如果你尝试用一个较老的JDK来指定--add-modules ,它将会炸毁,因为这是一个无法识别的选项。 我build议两种select之一:

  1. 您可以通过检查JAVA_VERSION属性的$JAVA_HOME/release来检查JDK版本,从而在启动脚本中有条件地应用参数(如果有的话)。
  2. 您可以添加-XX:+IgnoreUnrecognizedVMOptions以使JVM以静默方式忽略未经批准的选项,而不是炸毁。 但要小心! 您使用的任何其他命令行参数将不再由JVMvalidation。 此选项适用于Oracle / OpenJDK以及IBM JDK(从JDK 8sr4开始)

备用解决scheme:
请注意,通过指定--add-modules java.se.ee选项,可以使所有上述Java EE模块在运行时可用。 java.se.ee模块是一个包含java.se.ee以及上述Java EE API模块的聚合模块。

尽pipeJava 10还有很长的路要走,但值得注意的是,所有上述的Java EE API模块都被标记为@Deprecated(forRemoval=true) ,所以它们在未来的Java版本中被移除是公平的游戏! 为了最大限度地面向未来,您应该养成在类path或模块path中指定自己的Java EE API拷贝的习惯。

有关Java模块化的完整详细信息,请参阅JEP 261页面: http : //openjdk.java.net/jeps/261

这对我工作:

 <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> 

作为我的Java 8应用程序的依赖项,它生成一个* .jar,可以由JRE 8或JRE 9运行,不需要额外的参数。

另外,这需要在使用JAXB API之前执行:

 System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory"); 

作为一个解决方法,到目前为止效果很好。 虽然看起来不是一个完美的解决scheme

在编译时以及运行时,添加开关--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

对于Java Web Start Execution,我们可以使用Andy Guibert的build议:

 <j2se version="1.6+" java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/> 

注意–add-modules中额外的“=”。 请参阅此OpenJDK故障单或Java Platform Standard Edition Oracle JDK 9迁移指南的 “了解运行时访问警告”中的最后一个注释。

您可以使用“ –add-modules = java.xml.bind ”JVM选项将xml绑定模块添加到JVM运行时环境。

例如:“java –add-modules = java.xml.bind XmlTestClass”