Java EE API的替代方案用于已弃用的JPMS模块

292

Java 9 弃用了六个包含Java EE API的模块,它们即将被删除:

  • java.activation 包含 javax.activation
  • java.corba 包含 javax.activityjavax.rmijavax.rmi.CORBAorg.omg.*
  • java.transaction 包含 javax.transaction
  • java.xml.bind 包含所有 javax.xml.bind.*
  • java.xml.ws 包含 javax.jwsjavax.jws.soapjavax.xml.soap 和所有 javax.xml.ws.*
  • java.xml.ws.annotation 包含 javax.annotation

哪些维护的第三方工件提供了这些API?它们提供这些API的好坏或其他功能并不重要,重要的是,它们是否可以直接替换这些模块/包?

为了更容易地收集知识,我已回答了我所知道的,并将答案作为社区Wiki。我希望人们能扩展它,而不是写自己的答案。


在你投票关闭之前:

  • 是的,已经有一些关于单个模块的问题以及对这个问题的回答会重复这些信息。但据我所知,没有一个单一的地方可以了解所有这些信息,我认为这有很大的价值。
  • 通常认为询问库推荐的问题是不适合的,因为“它们往往会吸引有意见的答案和垃圾邮件”,但我认为这里并不适用。有效库的集合清晰地描绘出来:它们必须实现特定的标准。除此之外,没有其他的要求,因此我认为风险很小,不会有意见和垃圾邮件。

9
大多数这些项目都被转移至 https://github.com/javaee,并在 JEP 320: Remove the Java EE and CORBA Modules 中提供了一些具体链接。 - Naman
1
请参阅2018年5月14日InfoWorld文章,Java路线图:Eclipse的Jakarta EE企业Java正在成形,作者是Paul Krill。副标题:Eclipse基金会概述了将组成新的云原生、微服务友好型企业Java努力的39个项目,以及GlassFish将如何发展。 - Basil Bourque
2
从JDK 11开始,它已被删除。如果您正在使用jdk 9或以上版本,则最好直接添加依赖项,而不是使用"--add-modules java.xml.bind"这种东西。 - Anver Sadhat
11个回答

322

不要使用已经过时的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>

(来源)

CORBA (java.corba)

来自JEP 320:

除非第三方接管CORBA API、ORB实现、CosNaming提供者等,否则将不会有独立的CORBA版本。Java SE平台支持CORBA的独立实现,因此第三方维护是可能的。相比之下,RMI-IIOP的API在Java SE内部定义和实现。除非启动专门的JSR来维护它,或者Eclipse基金会接管API的管理权(Java EE从JCP到Eclipse基金会的管理权转移包括GlassFish及其CORBA和RMI-IIOP实现),否则将不会有独立的RMI-IIOP版本。

JTA (java.transaction)

独立版本:

<dependency>
    <groupId>jakarta.transaction</groupId>
    <artifactId>jakarta.transaction-api</artifactId>
    <version>1.3.3</version>
</dependency>

(源代码)

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参考实现页面

@Abhijit Sarkar提出了替代运行时,因为com.sun.xml.bind:jaxb-impl已被弃用

schemagenxjc也可以从那里下载作为独立的JAXB发行版的一部分。

另请参见链接的答案

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>

独立分发下载(包含 wsgenwsimport)。

常见注解 (java.xml.ws.annotation)

Java Commons Annotations(可在 Maven Central 上获取):

<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>1.3.5</version>
</dependency>

(来源)


1
如果一个模块从JDK和com.sun.xml.ws依赖项中都读取jax-ws,该怎么办? - nllsdfx
1
我不确定你具体在问什么。哪个模块读取jax-ws?如果在模块图中有_java.xml.ws_,并且在类路径上有_com.sun.xml.ws:jaxws-ri_,则后者将被忽略(因为分割包)。 - Nicolai Parlog
关于JAXB替代方案。jaxb-core和jaxb-impl都包含相同的包名“com.sun.xml.bind”,会在JPMS模块化应用程序中导致“分割包”错误。如果两者同时存在,它将无法工作。 - Terran
1
没错。两个细节:(1)如果没有显式模块(即带有模块声明的模块)依赖于JAXB,则仍然可以将它们放在类路径中,其中分割包无关紧要。(2) 命令行选项--patch-module可以修复此问题。 - Nicolai Parlog
2
com.sun.xml.bind:jaxb-impl已被弃用(https://search.maven.org/artifact/com.sun.xml.bind/jaxb-impl)。新的运行时是`org.glassfish.jaxb:jaxb-runtime`。 - Abhijit Sarkar
显示剩余12条评论

35

JAXB (java.xml.bind) 适用于JDK9

在我的桌面应用程序中,完美地运行于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>

6
谢谢,这个方法对我在Java 10上使用有效。然而,将版本号2.3.0的单个属性同时用于jaxb-apijaxb-runtime不是一个好主意。Glassfish运行时目前为2.3.0.1,而API仍然保持在2.3.0。我建议在答案中完全删除properties元素,并且分别在每个dependency中硬编码每个版本号。 - Basil Bourque
我的建议是:在 <dependencyManagement> 中导入 org.glassfish.jaxb:jaxb-bom BOM 的某个版本(目前最新的是2.3.0.1),然后在实际的 <dependencies> 部分,不要为 jaxb-apijaxb-runtime 指定版本号。版本号将从 BOM 中获取,这将确保它们始终保持同步并一起升级。 - AndrewF
3
JAXB 2.3.[0|1] 将不再适用于 Java 11!请参见 https://github.com/eclipse-ee4j/jaxb-api/issues/78。 - col.panic

13

我需要替换我的基于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被描述为“旧”,并且根据这个答案,使用基于org.glassfish 的东西,它也带来了org.eclipse.yasson

现在情况非常混乱,虽然它可以工作,但是怎么能确定它是最佳替代品呢?


1
我们也在使用Gradle,但我没有取得任何进展。尝试将Maven的解决方案转换为Gradle,但没有成功。您的示例对我有用(虽然我使用了compile而不是provided,我尝试迁移的项目正在使用Vertx)。感谢分享,确实,我也希望很快会有关于Gradle的一些澄清 :) - Lars
请注意,情况变化非常快 - 最近我将另一个项目迁移到了Spring Boot 2.2,其中Jakarta API更为突出,但我们仍然需要实现。为此,我仍然使用org.glassfish.*的东西。每当我使用Spring Boot项目时,我倾向于检查它们的依赖版本附录,并尽可能遵守(将当前版本更改为您需要的版本):https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-dependency-versions.html - virgo47

8

1
可能是因为这更适合作为评论而不是答案。无论如何,你能解决这个问题吗?我似乎无法检索到依赖项。mvn -U clean install 一直显示 Could not find artifact commonj.sdo:commonj.sdo:jar:2.1.1.v201112051852 - Zyl
1
我不是Maven专家,但似乎在pom.xml中未声明任何存储库时,它会找到commonj.sdo:commonj.sdo:jar:2.1.1.v201112051852。如果pom.xml中有存储库(如spring-snapshot),则还必须添加http://download.eclipse.org/rt/eclipselink/maven.repository,例如 <repository> <id>my-id</id> <name>eclipse-repo</name> <url>http://download.eclipse.org/rt/eclipselink/maven.repo</url> </repository> 附言:如果我的声望足够高,我会添加评论而不是答案 :) - theNikki1
2
我已经让它工作了,但我还必须从我的settings.xml中删除一个镜像。然而,经过进一步的检查,我无法重现这是替代弃用包的方式。相反,我发现了这个很好用的依赖项: javax.jws jsr181-api 1.0-MR1 - Zyl
1
我成功地排除了sdo-eclipselink-plugin包。 - Joseph Lust

5

以下是对上述答案的微小变化(改进)--- 仅以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>

5
我在我的Spring MVC项目中使用jdk 11 + ant + ivy。我遇到了错误"package javax.jws does not exist",所以我将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>

2
您可以通过Maven的依赖解析系统正确地引入它:<dependency> <groupId>javax.jws</groupId> <artifactId>javax.jws-api</artifactId><version>1.1</version> </dependency>,它可以正确地解析“javax.jws”类。 - msteiger

3
如果您在Talend中(例如7.x版本)遇到此问题,您可以在项目的默认POM.xml中添加:
<dependencies>
    <dependency>
        <groupId>javax.xml.soap</groupId>
        <artifactId>javax.xml.soap-api</artifactId>
        <version>1.4.0</version>
    </dependency>
</dependencies>

测试结果:

  • AdoptJDK 8.0.275.1-hotspot :正常
  • AdoptJDK 11.0.9.101-hotspot :正常
  • AdoptJDK 15.0.1.9-hotspot :不正常(但这是另一个问题:不兼容的条件操作数类型异常和TDieException)
  • Zulu-8.50.0.1017 :正常
  • Zulu-11.43.1015 :正常

2

作为2022年的一名IT从业者,我深切感受到这个问题的痛苦!虽然尝试了很多上面提到的建议,但只有在使用以下依赖项时才能使其正常工作。

<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>

注意:不要被诱惑更新依赖项,保持原样就可以,这对我有效。

2
我已经尝试了上述大部分使用JDK 11.0.3的建议,但并没有成功。我最终找到的唯一解决方案如下。可能有其他可行的选项,但似乎版本的选择至关重要。例如,将com.sun.xml.ws:rt更改为2.3.2会导致javax.jws模块不再可用。最初的回答:我尝试过上面提到的大部分建议,使用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> 

2
如果您遇到相同的问题,请将以下依赖项添加到pom.xml文件中。
<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.3.3</version>
</dependency>

然后使用JAVA 8作为备选JRE。有关更多详细信息,请参阅此视频,这对我很有帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接