在不定义其他模块的情况下,使用Spring JAXB Marshaller和Java 9的正确方法

为了说明我的问题,我创建了一个小的spring boot示例应用程序。 该应用程序的目的是创建一个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"); } } 

此代码无法启动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 

我不明白这个exception是为什么com.sun.xml.internal.bind.v2.ContextFactory试图实例化? 有人建议 ,我还需要运行时的依赖项,所以我补充说:

  org.glassfish.jaxb jaxb-runtime 2.3.0  

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

 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

   4.0.0 ch.sahits.game AddModuleDependencies 1.0.0-SNAPSHOT  2.3.0    org.springframework.boot spring-boot-starter 2.0.0.RELEASE   org.springframework spring-oxm 5.0.4.RELEASE compile   javax.xml.bind jaxb-api 2.3.0   javax.annotation javax.annotation-api 1.3.2   org.glassfish.jaxb jaxb-runtime 2.3.0      src/main/resources     maven-compiler-plugin 3.7.0  9 9    org.apache.cxf cxf-xjc-plugin ${cxf-xjc-plugin.version}   generate-sources generate-sources  xsdtojava    org.apache.cxf.xjcplugins:cxf-xjc-dv:${cxf-xjc-plugin.version}    src/main/resources/helloworld.xsd src/main/resources/jaxb-binding.xjb ch.sahits.game.helloworld          

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

MCVE 下载为zip存档。

尝试添加以下内容:

  org.glassfish.jaxb jaxb-core 2.3.0   com.sun.activation javax.activation 1.2.0  

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

此外,没有单个bean类,因此编组器将无法初始化。 我添加了以下内容

 @XmlRootElement public class MyBean { } 

并取代

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

 bean.setClassesToBeBound(MyBean.class); 

之后应用程序已启动。

以下对我有用

  org.glassfish.jaxb jaxb-runtime 2.3.0