在 Java 9 中使用 Spring JAXB Marshaller 而不定义其他模块的正确方法

为了说明我的问题,我创建了一个小型 Spring Boot 示例应用程序.该应用程序的目的是创建一个 Jaxb2Marshaller bean.

To illustrate my issue, I created a small spring boot sample application. The purpose of the application is to create a Jaxb2Marshaller bean.

@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");
    }
}

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

This code fails to start up with the exception:

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 试图实例化?有人建议,我也需要一个依赖一个运行时,所以我添加了:

What I do not understand about this exception is why the com.sun.xml.internal.bind.v2.ContextFactory is tried to instantiate? It has been suggested, that I also need a dependency for a runtime, so I added:

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

但这只会让我遇到一个不同的异常,尝试加载不同的类:

But that only got me a different exception, trying to load a different class:

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... 的类)?

The simple solution of course is to add --add-modules java.xml.ws as a VM option, but that is exactly what I am trying to get rid off to make my application future proof. What dependency do I have to use to resolve this issue? Or do I have change the bean configuration, so that the proper classes are looked up (and not the ones from com.sun.xml... )?

下载的 MCVE 压缩包.

The MCVE for download as zip archive.

推荐答案

以下对我有用

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

相关文章