在不定义其他模块的情况下将Spring JAXB Marshaller与Java 9一起使用的正确方法



为了说明我的问题,我创建了一个小型的 Spring 启动示例应用程序。该应用程序的目的是创建一个Jaxb2MarshallerBean。

@SpringBootApplication
public class App implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Bean
public Jaxb2Marshaller jaxb2Marshaller() {
Jaxb2Marshaller bean = new Jaxb2Marshaller();
bean.setContextPath("ch.sahits.game.helloworld");
return bean;
}
@Override
public void run(String... args) throws Exception {
System.out.println("Started up");
}
}

此代码无法启动,出现异常:

Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)
at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:174)
... 23 more

我不明白这个异常的是为什么尝试实例化com.sun.xml.internal.bind.v2.ContextFactory?有人建议,我也需要一个运行时的依赖项,所以我添加了:

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

但这只会给我一个不同的例外,试图加载一个不同的类:

Caused by: java.lang.ClassNotFoundException: com.sun.xml.bind.v2.model.annotation.AnnotationReader
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
... 39 more

以下是完整的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.sahits.game</groupId>
<artifactId>AddModuleDependencies</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<cxf-xjc-plugin.version>2.3.0</cxf-xjc-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>5.0.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-plugin</artifactId>
<version>${cxf-xjc-plugin.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>xsdtojava</goal>
</goals>
<configuration>
<extensions>
<extension>org.apache.cxf.xjcplugins:cxf-xjc-dv:${cxf-xjc-plugin.version}</extension>
</extensions>
<xsdOptions>
<xsdOption>
<xsd>src/main/resources/helloworld.xsd</xsd>
<bindingFile>src/main/resources/jaxb-binding.xjb</bindingFile>
<packagename>ch.sahits.game.helloworld</packagename>
</xsdOption>
</xsdOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

当然,简单的解决方案是将--add-modules java.xml.ws添加为 VM 选项,但这正是我试图摆脱的,以使我的应用程序面向未来。 我必须使用什么依赖项来解决此问题?或者我是否更改了 bean 配置,以便查找正确的类(而不是来自com.sun.xml...的类(?

MCVE 下载为 zip 存档。

尝试添加以下内容:

<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>

jaxb-core包含com.sun.xml.bind.v2.model.annotation.AnnotationReader(并且似乎是jaxb-runtime的必要依赖项,至少在您的情况下(,而javax.activation由于后者使用DataHandlerjaxb-api需要

。此外,没有单个 Bean 类,因此编组器初始化失败。我添加了以下内容

@XmlRootElement
public class MyBean {
}

并更换

bean.setContextPath("ch.sahits.game.helloworld");

bean.setClassesToBeBound(MyBean.class);

之后应用程序已启动。

以下内容对我有用

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

连接"Spring OXM"对我有帮助:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
</dependency>

相关内容

最新更新