使用 Java EE API 替换已弃用的 JPMS 模块
Posted
技术标签:
【中文标题】使用 Java EE API 替换已弃用的 JPMS 模块【英文标题】:Replacements for deprecated JPMS modules with Java EE APIs 【发布时间】:2018-06-20 14:38:47 【问题描述】:Java 9 deprecated six modules that contain Java EE APIs 很快就会成为 going to be removed:
java.activation 带有javax.activation
包
java.corba 带有 javax.activity
、javax.rmi
、javax.rmi.CORBA
和 org.omg.*
包
java.transaction 带有javax.transaction
包
java.xml.bind 与所有 javax.xml.bind.*
包
java.xml.ws 与 javax.jws
、javax.jws.soap
、javax.xml.soap
和所有 javax.xml.ws.*
包
java.xml.ws.annotation 带有javax.annotation
包
哪些维护的第三方工件提供了这些 API?它们提供这些 API 的能力如何或它们必须提供哪些其他功能并不重要——重要的是,它们是这些模块/包的直接替代品吗?
为了更容易收集知识,我用我目前所知道的内容进行了回答,并将答案制作为社区 wiki。我希望人们将其扩展而不是编写自己的答案。
在您投票结束之前:
是的,已经有一些关于各个模块的问题,并且对这个问题的回答当然会重复该信息。但是 AFAIK 没有任何一点可以了解所有这些,我认为这很有价值。 要求图书馆推荐的问题通常被认为是题外话,因为“它们往往会吸引固执己见的答案和垃圾邮件”,但我认为这不适用于这里。一组有效的库被清楚地描述:它们必须实现一个特定的标准。除此之外,其他一切都不重要,因此我认为意见和垃圾邮件的风险不大。【问题讨论】:
您可以在github.com/javaee 下找到所有被移动的人,并在JEP 320: Remove the Java EE and CORBA Modules 上找到一些细节的链接 另请参阅 InfoWorld 中的这篇 2018-05-14 文章,Java roadmap: Eclipse’s Jakarta EE enterprise Java takes shape,作者是 Paul Krill。副标题:Eclipse 基金会概述了组成新的云原生、微服务友好型企业 Java 工作的 39 个项目,以及 GlassFish 将如何发展 从 JDK 11 中它已被删除。如果您使用的是 jdk 9 或更高版本,最好直接添加依赖项,而不是使用“--add-modules java.xml.bind”之类的东西 【参考方案1】:不要使用已弃用的 Java EE 模块,而是使用以下工件。
JAF (java.activation)
JavaBeans Activation Framework(现为Jakarta Activation)是一项独立技术(可在 Maven Central 上获得):
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
<version>1.2.2</version>
</dependency>
(Source)
CORBA (java.corba)
来自JEP 320:
除非第三方接管 CORBA API、ORB 实现、CosNaming 提供者等的维护,否则不会有独立版本的 CORBA。第三方维护是可能的,因为 Java SE 平台支持 CORBA 的独立实现。相比之下,RMI-IIOP 的 API 仅在 Java SE 中定义和实现。除非启动专门的 JSR 来维护 RMI-IIOP,否则不会有独立版本的 RMI-IIOP,或者 API 的管理权由 Eclipse 基金会接管(Java EE 的管理权从 JCP 到 Eclipse 基金会的过渡包括@ 987654323@及其CORBA和RMI-IIOP的实现)。
JTA (java.transaction)
单机版:
<dependency>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
<version>1.3.3</version>
</dependency>
(Source)
JAXB (java.xml.bind)
自从 Java EE更名为 Jakarta EE,JAXB 现在由新的工件提供:
<!-- API -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
<!-- Runtime -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
<scope>runtime</scope>
</dependency>
<!-- Alternative runtime -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
<scope>runtime</scope>
</dependency>
JAXB Reference Implementation page.
替代运行时是brought up by Abhijit Sarkar。
schemagen
和 xjc
也可以作为独立 JAXB 发行版的一部分从那里下载。
另见linked answer。
JAX-WS (java.xml.ws)
参考实现:
<!-- API -->
<dependency>
<groupId>jakarta.xml.ws</groupId>
<artifactId>jakarta.xml.ws-api</artifactId>
<version>2.3.3</version>
</dependency>
<!-- Runtime -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
Standalone distribution download(包含wsgen
和wsimport
)。
常用注解(java.xml.ws.annotation)
Java Commons Annotations(在 Maven 中心可用):
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>1.3.5</version>
</dependency>
(Source)
【讨论】:
如果模块从 jdk 和com.sun.xml.ws
依赖中读取 jax-ws
怎么办?
我不确定你到底在问什么。哪个模块读取 jax-ws?如果您在模块图中有 java.xml.ws 并且在类路径中有 com.sun.xml.ws:jaxws-ri,则后者将被忽略(因为split packages)。
好吧,我想在我的模块中使用com.sun.xml.ws:jaxws-ri
而不是java.xml.ws
,因为后者已被弃用并将被删除。我将依赖项添加到我的 pom 文件中,出现错误“模块 xyz 从 'java.xml.ws' 和 'java.xml.ws' 读取包 'javax.xml.ws'”。
看起来模块 java.xml.ws 终于被解析了,可能是因为--add-modules
或者因为其他一些模块需要它。你能打开一个新问题,让我们看看吗?
确实如此。两个细节:(1)如果没有显式模块(即具有模块声明的模块)依赖于 JAXB,您仍然可以将它们放在类路径上,其中拆分包无关紧要。 (2) 命令行选项--patch-module
可以补分割。【参考方案2】:
JDK9 的 JAXB (java.xml.bind)
在 jdk9/10 EA 上的桌面应用程序中完美运行
<properties>
<jaxb-api.version>2.3.0</jaxb-api.version>
</properties>
<!-- JAXB 2.3.0 for jdk9+ -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>$jaxb-api.version</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>$jaxb-api.version</version>
</dependency>
<!-- JAXB needs javax.activation module (jdk9) -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
【讨论】:
谢谢,这在 Java 10 上对我有用。但是,对于jaxb-api
和 jaxb-runtime
使用版本号 2.3.0
的单个属性并不是一个好主意。 Glassfish runtime is currently at 2.3.0.1
,而 API 保持在 2.3.0
。我建议在答案中完全删除 properties
元素,并分别在每个 dependency
中硬编码每个版本号。
我的建议:在<dependencyManagement>
中,导入某个版本的org.glassfish.jaxb:jaxb-bom
BOM(现在最新的是2.3.0.1),然后在实际的<dependencies>
部分中,不要指定版本jaxb-api
或 jaxb-runtime
。版本号将从 BOM 中获取,这将确保它们始终保持同步并一起升级。
JAXB 2.3.[0|1] 将不再适用于 Java 11!见github.com/eclipse-ee4j/jaxb-api/issues/78【参考方案3】:
似乎 jaxws-ri 可传递地依赖于 commonj.sdo:commonj.sdo:jar:2.1.1.v201112051852,这显然可以从存储库 http://download.eclipse.org/rt/eclipselink/maven.repo 中找到
【讨论】:
可能是因为它更适合评论而不是答案。无论如何,你能解决问题吗?我似乎无法检索依赖项。mvn -U clean install
一直说Could not find artifact commonj.sdo:commonj.sdo:jar:2.1.1.v201112051852
。
我不是 Maven 专家,但是当 pom.xml 中没有声明存储库时,它似乎正在寻找 commonj.sdo:commonj.sdo:jar:2.1.1.v201112051852。如果 pom.xml 中有存储库(如 spring-snapshot),还必须添加 download.eclipse.org/rt/eclipselink/maven.repository,例如 <dependency> <groupId>javax.jws</groupId> <artifactId>jsr181-api</artifactId> <version>1.0-MR1</version> </dependency>
我只能排除包sdo-eclipselink-plugin
【参考方案4】:
我需要为基于 Spring Boot 2 的应用程序替换 JAX-WS (java.xml.ws) 和 JAXB (java.xml.bind),最终得到了这些 JAR(Gradle 构建):
// replacements for deprecated JDK module java.xml.ws
runtimeOnly 'javax.xml.ws:jaxws-api:2.3.0' // javax.xml.ws.* classes
runtimeOnly 'javax.jws:jsr181-api:1.0-MR1' // for javax.jws.* classes
// replacement for deprecated JDK module java.xml.bind
runtimeOnly 'javax.xml.bind:jaxb-api'
runtimeOnly 'org.glassfish.jaxb:jaxb-runtime:2.3.0.1'
runtimeOnly 'org.glassfish:javax.json:1.1.2'
runtimeOnly 'org.eclipse:yasson:1.0.1'
(您可能需要compile
或其他范围,runtimeOnly
对我们来说已经足够了。)
我注意到https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core 被描述为“旧”,并且使用this answer 用于基于org.glassfish
的东西也带来了org.eclipse.yasson
。
现在情况真的很混乱,它可以工作,但任何人都应该如何确定它是最好的替代品,对吧?
【讨论】:
我们也在使用 gradle,但我一无所获。试图将 maven 解决方案翻译成 gradle 但没有成功。您的示例对我有用(虽然使用了编译,但未提供,我尝试迁移的项目正在使用 vertx)。感谢分享,事实上,我也希望很快会有关于 gradle 的一些澄清:) 请注意,情况发展得很快——就在最近我将另一个项目转移到 Spring Boot 2.2,Jakarta API 更加突出,但我们仍然需要实现。为此,我仍然使用 org.glassfish.* 的东西。每当我使用 Spring Boot 项目时,我倾向于检查它们的依赖版本附录并尽可能地遵守(将当前更改为您需要的版本):docs.spring.io/spring-boot/docs/current/reference/html/…【参考方案5】:我发现解决这些问题的 JAXB 部分的最简单方法是在我的根 pom 或我的 bom 中使用依赖管理:
<project ...>
<dependencyManagement>
<dependencies>
<!-- ... -->
<!-- Gone from jvm in java11 -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-ri</artifactId>
<version>2.4.0-b180830.0438</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<!-- ... -->
</dependencies>
</dependencyManagement>
</project>
在 jdk11 上编译失败的模块中:
<!-- ... -->
<dependencies>
<!-- Gone from jvm in java11 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<scope>runtime</scope>
</dependency>
<!-- ... -->
</dependencies>
<!-- ... -->
另外,将org.jvnet.jaxb2.maven2:maven-jaxb2-plugin
的版本更新为 0.14.0 为我解决了所有 jaxb 生成问题。
【讨论】:
【参考方案6】:上述答案只是一个微小的变化(改进)——此处仅针对 JAXB 举例说明。可以使用 runtime
范围添加依赖项,并且仅在有效需要的情况下(即,在构建以在版本 >= 9 的 JRE 中运行时 --- 这里以 v11 为例):
<profile>
<id>when-on-jdk-11</id>
<activation>
<jdk>11</jdk>
</activation>
<properties>
<!-- missing artefacts version properties -->
<jaxb-api.version>2.3.1</jaxb-api.version>
<jaxb-impl.version>2.3.2</jaxb-impl.version> <!-- one might let it the same with the jaxb-api.version -->
</properties>
<dependencies>
<!-- runtime dependencies to avoid JAXB related CNF exceptions when running on Java 11 (e.g.: ClassNotFoundException: javax.xml.bind.annotation.XmlType) -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>$jaxb-api.version</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>$jaxb-impl.version</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
【讨论】:
【参考方案7】:我已经使用 JDK 11.0.3 对上述大多数建议进行了试验,但都没有成功。我最终发现唯一可行的解决方案如下。也许还有其他选项也有效,但似乎版本的选择至关重要。例如,将 com.sun.xml.ws:rt 更改为 2.3.2 会导致模块 javax.jws 不再可用。
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.4.0-b180830.0438</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>rt</artifactId>
<version>2.3.1</version>
</dependency>
【讨论】:
【参考方案8】:我在我的 spring mvc 项目中使用 jdk 11 + ant + ivy。
我收到错误“package javax.jws 不存在”所以我将 javax.jws-api-1.1.jar 添加到 classpath 并且它工作!
只需从https://repo1.maven.org/maven2/javax/jws/javax.jws-api/1.1/javax.jws-api-1.1.jar下载jar
并将其添加到 build.xml
中的类路径中
或者将其添加到您的pom.xml
:
<dependency>
<groupId>javax.jws</groupId>
<artifactId>javax.jws-api</artifactId>
<version>1.1</version>
</dependency>
【讨论】:
您可以通过 Maven 的依赖解析系统正确包含它:<dependency> <groupId>javax.jws</groupId> <artifactId>javax.jws-api</artifactId><version>1.1</version> </dependency>
,它实际上正确解析了“javax.jws”类。【参考方案9】:
如果您在 Talend(例如 7.x)中遇到此问题,您可以在项目的 Default POM.xml 中添加:
<dependencies>
<dependency>
<groupId>javax.xml.soap</groupId>
<artifactId>javax.xml.soap-api</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
经过测试:
采用JDK 8.0.275.1-hotspot:好的 采用JDK 11.0.9.101-hotspot:好的 AdoptJDK 15.0.1.9-hotspot : KO(但这是另一个问题:不兼容的条件操作数类型 Exception 和 TDieException) Zulu-8.50.0.1017:好的 Zulu-11.43.1015:好的【讨论】:
【参考方案10】:如果您有同样的问题,请将以下依赖项添加到 pom.xml
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
然后使用 JAVA 8 作为替代 JRE。有关更多详细信息,请关注https://www.youtube.com/watch?v=pgSJda16N54 视频,它对我有用。
【讨论】:
【参考方案11】:截至 2022 年,这确实是一种真正的痛苦! 我尝试了许多上述建议,但只能让它与以下依赖项一起使用。
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
注意:不要试图更新依赖项,就这样吧,它对我有用。
【讨论】:
以上是关于使用 Java EE API 替换已弃用的 JPMS 模块的主要内容,如果未能解决你的问题,请参考以下文章
如何用新的 Blob 构造函数替换已弃用的 BlobBuilder?