21

我们使用maven并拥有依赖于其他内部工件的工件。我正在迁移到,并打算首先将所有内容迁移到 Java 9 而不模块化代码(即在未命名的模块中)。

我遇到的问题是我们依赖于java.xml.bind,它现在不包含在默认模块中。是否有一种“正确”的方式来表达对java.xml.bindMaven 的这种依赖?

4

4 回答 4

21

模块系统谈到了未命名模块的方式,例如从类路径加载应用程序的情况下构建模块图的方式。此外,从文档本身来看: -

当编译器编译未命名模块中的代码,或者调用 java 启动器并将应用程序的主类从类路径加载到应用程序类加载器的未命名模块中时,则未命名模块的默认根模块集计算如下:

  • java.se模块是一个根,如果它存在的话。如果它不存在,则java.*升级模块路径上或系统模块中的每个模块,exports至少一个包,没有资格,是一个根。

  • non-java.*升级模块路径上或系统模块中的每个模块,exports至少有一个包,没有限定,也是一个根。

否则,默认的根模块集取决于阶段:

  • 在编译时,它通常是正在编译的模块集(更多内容见下文);

  • 在链接时它是空的;和

  • 在运行时,它是应用程序的主模块,通过 --module(或简称 -m)启动器选项指定。

有时需要将模块添加到默认根集中,以确保特定平台、库或服务提供者模块将出现在模块图中。在任何阶段的选项

--add-modules <module>(,<module>)*其中<module>是模块名称,将命名模块添加到默认的根模块集中。

jetty.project中也遇到了类似的问题,其中讨论了来自 jdk 邮件列表的线程,修复方法是使用:

--add-modules java.se.ee

这为他们提供了对所有 Java SE 模块的访问权限,在您的情况下应该是:

--add-modules java.xml.bind

要在 Maven 中使用它,您可以将其嵌入到maven-compiler-plugin using

<compilerArgs>
    <arg>--add-modules</arg>
    <arg>java.xml.bind</arg>
</compilerArgs>

正如 ZhekaKozlov在这里所建议的那样。


需要注意的重要一点是,标记 API 的弃用也意味着您可能希望不再使用它。jaxb-api:2.3.0为了适应这种方式,您可能可以开始使用现在可以作为模块加载并且也可以从类路径执行的依赖项。您需要进行的更改是将以下内容添加到您的依赖项列表中:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>

更新:- 最终,随着 Java-10 和 JDK/11 的推出,理想情况下应该遵循JEP 320 的链接:删除 Java EE 和 CORBA 模块,并用它们的独立库进一步替换这些依赖项。

于 2017-09-07T02:26:11.070 回答
11

是的,您必须传递--add-modules给 Java 编译器:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.7.0</version>
    <configuration>
        <release>9</release>
        <compilerArgs>
            <arg>--add-modules</arg>
            <arg>javax.xml.bind</arg>
        </compilerArgs>
    </configuration>
</plugin>

然后你的项目应该编译得很好。

于 2017-09-07T02:35:13.170 回答
9

JAXB 以及与 Java EE 共享的其他 API(JAX-WS、JAF、JTA 和所谓的“Common Annotations”)在 Java SE 9 中已弃用,并建议在 Java SE 的未来版本中删除,并且JDK。这些 API 中的每一个都有一个独立的版本/下载。每个 API 都有自己的 JSR 来维护它。从 JDK 中包含的 API 转换到独立版本当然会有点破坏性。

从 Java SE 和 JDK 中删除这些 API 的第一步是默认不解析包含这些 API 的模块。当您使用 JDK 9 在类路径上编译或运行代码时,最初会显示 API 不存在。如另一个答案中所述,一种快速的解决方法是使用--add-modules java.xml.bind. 该 CLI 选项将“java.xml.bind”模块添加到根模块集以在启动时解析,并且它适用于 JDK 9,因为该模块包含在 JDK 运行时映像中。

除了快速解决方法之外,使用 JAXB 的应用程序或库还需要转为使用 API/实现的独立版本。JAXB 2.3.0 即将发布到 Maven Central,其中包括与 JDK 9 及更高版本一起使用的更改。独立版本可以像其他 JAR 文件一样部署在类路径上。最终可以在(升级)模块路径上部署独立版本并将其也用作模块。JDK 9 迁移指南将提供有关迁移使用 JAXB 或与 Java EE 共享的其他 API 的代码的选项的更多信息。

于 2017-09-07T07:32:14.687 回答
2

好的,我希望这对某人有所帮助。如果您有机会安装了 Java 9 或 10 并且发现您无法克服这个javax.xml.bind错误,那么您可能正在通过每个文件夹的jenv使用 Java 8 (真的很抱歉这么含糊,但是,这就是我目前所有的时间)?

但是为 JAVA_HOME 添加正确的设置解决了我的问题:export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"在 MacOS 上。

于 2018-08-14T18:42:08.263 回答