如何在 maven 中表达对 java ee 功能的依赖以过渡到 Java 9?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46084751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:03:39  来源:igfitidea点击:

How to express dependency in maven on java ee features for transition to Java 9?

javamavenjaxbjava-9jigsaw

提问by Kevin Peterson

We use mavenand have artifacts that in turn depend on other internal artifacts. I am in the process of migrating to java-9, and intend to migrate everything to Java 9 first without modularizing the code (i.e. in the unnamed module).

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

The problem I run into is that we depend on java.xml.bind, which is now not included in the default modules. Is there a "correct" way to express this dependency on java.xml.bindwith Maven?

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

回答by Naman

The Module Systemspeaks of the way the unnamed modules as in your case of loading the application from classpath constructs the module graph. Further, from the documentation itself:-

模块系统讲的无名模块作为在从类路径加载应用的情况下构建模块图的方式。此外,从文档本身: -

When the compiler compiles code in the unnamed module, or the java launcher is invoked and the main class of the application is loaded from the class path into the unnamed module of the application class loader, then the default set of root modules for the unnamed module is computed as follows:

  • The java.semodule is a root, if it exists. If it does not exist then every java.*module on the upgrade module path or among the system modules that exportsat least one package, without qualification, is a root.

  • Every non-java.*module on the upgrade module path or among the system modules that exportsat least one package, without qualification, is also a root.

Otherwise, the default set of root modules depends upon the phase:

  • At compile time it is usually the set of modules being compiled (more on this below);

  • At link time it is empty; and

  • At run time it is the application's main module, as specified via the --module(or -m for short) launcher option.

It is occasionally necessary to add modules to the default root set in order to ensure that specific platform, library, or service-provider modules will be present in the module graph. In any phase the option

--add-modules <module>(,<module>)*where <module>is a module name, adds the named modules to the default set of root modules.

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

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

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

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

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

  • 链接时为空;和

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

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

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

Similar issue was faced in jetty.projectwhere a threadfrom jdk mailing list discussed over the same and the fix was to use:

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

--add-modules java.se.ee

which provided them access to all Java SE modules and in your case shall simply be:

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

--add-modules java.xml.bind

To use this in maven, you can embed the same to the maven-compiler-pluginusing

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

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

as suggested by ZhekaKozlov here.

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



An important point to note is that marking deprecation of an API also means you might probably want to get away from using it. To adapt to this way you can probably start consuming the dependency on jaxb-api:2.3.0which can now be loaded as a module and can be executed from the classpath as well. The change you need to make is to add the following to your dependencies list:

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

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


Update:- Eventually, with Java-10 already out and JDK/11 up next, one should ideally follow the link to JEP 320: Remove the Java EE and CORBA Modulesand further replace such dependencies with their standalone libraries instead.

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

回答by ZhekaKozlov

Yes, you have to pass --add-modulesto Java compiler:

是的,您必须传递--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>

Then your project should compile fine.

那么您的项目应该可以正常编译。

回答by Alan Bateman

JAXB, along with the other APIs shared with Java EE (JAX-WS, JAF, JTA, and the so-called "Common Annotations") are deprecated in Java SE 9 and are proposed to be removed in a future release of Java SE and the JDK. Each of these APIs has a standalone version/download. Each API has its own JSR that maintains it too. Transitioning from the APIs included in the JDK to the standalone versions will of course be a bit disruptive.

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

A first step towards dropping these APIs from Java SE and the JDK is to not resolve the modules containing these APIs by default. When you compile or run code on the class path with JDK 9 then it will initially appear that the APIs do not exist. A quick workaround, as noted in another answer, is to compile or run with --add-modules java.xml.bind. That CLI option adds the "java.xml.bind" module to the set of root modules to resolve at startup and it works with JDK 9 because this module is included in the JDK run-time image.

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

Beyond the quick workaround, applications or libraries using JAXB will need to move to using the standalone version of the API/implementation. JAXB 2.3.0 is due to be published to Maven Central soon and it includes the changes to work with JDK 9 and beyond. The standalone version can be deployed on the class path like other JAR files. It will eventually be possible to deploy the standalone version on the (upgrade) module path and use it as a module too. The JDK 9 Migration Guide will have more information on the options for migrating code that uses JAXB or the other APIs shared with Java EE.

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

回答by Brett Tofel

Okay I hope this helps someone. If you, per chance, have installed Java 9 or 10 and find that you can't get past this javax.xml.binderror, perhaps you are using Java 8 by way of jenvper folder (really I am sorry to be so vague, but, that's all I have time for at the moment)?

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

But adding in a correct setting for JAVA_HOME fixed my problem: export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"on MacOS.

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