【问题标题】:Jakarta ee application best practice: should one use container-specific implementations?Jakarta ee 应用程序最佳实践:应该使用特定于容器的实现吗?
【发布时间】:2020-03-06 12:00:09
【问题描述】:

我正在构建我的第一个 Jakarta ee 8 应用程序。实际上我来自 Spring-Framework 背景,所以我专注于关键差异和最佳实践。我读到 Glassfish、Wildfly、JBoss EAP 等提供了 Jakarta ee 规范的实现。这就提出了一个问题:

Would the application be dependent on the server it runs on? If an upgrade or change of the application server is necessary, should one consider incompatibility bugs?

我将使用以下示例使问题更具体。

我使用 hello world JAX-RS Web 服务创建了两个版本的 Web 应用程序。它在 JBoss EAP 7.2.2 上运行。 第一个 pom 文件的样子

<dependency>
  <groupId>jakarta.platform</groupId>
  <artifactId>jakarta.jakartaee-api</artifactId>
  <version>8.0.0</version>
  <scope>provided</scope>
</dependency>

第二个pom文件

<dependencyManagement>
   <dependencies>
     <dependency>
        <groupId>org.wildfly.bom</groupId>
        <artifactId>wildfly-jakartaee8-with-tools</artifactId>
        <version>${version.jboss.bom}</version>
        <type>pom</type>
        <scope>import</scope>
     </dependency>
   </dependencies>
</dependencyManagement>
....
<dependency>
   <groupId>org.jboss.spec.javax.ws.rs</groupId>
   <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
   <scope>provided</scope>
</dependency>

根据以下链接>:http://www.mastertheboss.com/javaee/jakarta-ee/getting-started-with-jakarta-ee如果想对 Jakarta ee 使用 Wildfly 扩展,则应使用第二个 pom。

上运行上述应用程序
  • JBoss EAP -> EasyREST(JAX-RS 的 JBoss 实现)将发挥作用。
  • Glassfish -> 将使用泽西岛。应用程序 2 不会运行?
  • 在 Tomcat 上 -> 两者都不起作用,因为没有提供实现。

我知道我可以在我的 pom 中包含一个特定的 JAX-RS 库作为依赖项并独立于容器运行。但如果我在 JBoss EAP 或 Glassfish 等企业应用服务器上运行,那会是最佳实践吗?同时我还在考虑服务器的可移植性。

注意:我认为,当人们采用将所有实现作为显式依赖项包含在 WAR 中的方法时(例如,某个版本的 easyrest 或 Jersey),那么人们应该考虑切换到更轻量级 -像 Tomcat 一样重 servlet 容器,因为如果不使用其功能,在 Exnterprise 应用程序服务器上运行将没有任何好处。我在这里谈论的是 JAX-RS 示例。当然,当需要其他 J2EE 功能时,例如EJBs tomcat 肯定会被排除在外。

【问题讨论】:

  • Tomcat 本来就不是 JEE 服务器,所以这是一个不好的例子。

标签: jakarta-ee


【解决方案1】:

每当您使用特定于供应商的功能(例如 WildFly 的 RESTEasy 依赖项)时,您都无法轻松地将您的应用程序移植到不同的应用程序服务器(例如 Payara/Glassfish/Open Liberty)。

作为最佳实践,从 Jakarta EE API 依赖项开始:

<dependency>
  <groupId>jakarta.platform</groupId>
  <artifactId>jakarta.jakartaee-api</artifactId>
  <version>8.0.0</version>
  <scope>provided</scope>
</dependency>

这包括 JAX-RS 2.1 规范,所有应用程序服务器都支持开箱即用。如果您只使用它,您应该能够轻松地将您的应用程序移植到不同的服务器。

JAX-RS 2.1 specification covers 的功能很多,很可能就够用了。

可能存在一些边缘情况,规范未提供易于使用的解决方案,您可能希望包含特定于供应商的实现,这些实现不属于正式的 JAX-RS 规范的一部分。

一个很好的例子是缺少对 JAX-RS 的 MultiPart 数据的支持,例如将文件上传到您的后端。如果您将以下内容导入 Maven 项目,RESTEasy 会为此提供解决方案:

<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-multipart-provider</artifactId>
  <version>3.6.3.Final</version>
  <scope>provided</scope>
</dependency>

这里的缺点是,一旦您使用任何不是来自 javax.ws.rs/jakarta.ws.rs 的导入,您就会使用超出规范的东西。

另一方面,您还应该考虑切换应用程序服务器的可能性。

更新:

如果升级后的服务器实现仍然没有错误?

没有人知道实现是否没有错误。当你升级你的服务器版本时,你仍然应该计划一些时间来验证/测试。如果您依赖简单的 Jakarta EE 8 规范,这也是正确的。一般来说,服务器供应商也会花时间测试所有东西(拥有一个大的测试套件),并且可能已经发现了一些需要修复的错误。但是,您仍然不能 100% 确定升级服务器后一切都没有错误。

谈到升级应用程序服务器和 JAX-RS 后的错误,我在 Payara 中遇到了一个错误,其中我所有的 JAX-RS 请求过滤器都针对传入请求执行了两次。

顺便说一句。你不应该考虑Tomcat。 Tomcat 只是一个 servlet 容器,而不是完全符合 Jakarta EE 的应用程序服务器。在 Jakarta EE 主页上,您可以查看所有 Jakarta EE 8 compatible servers

【讨论】:

  • 感谢您的回答。你是对的,切换应用服务器的频率并不高,但我也考虑服务器升级。即使我坚持使用第一个 POM sn-p 的 API-SPEC,我仍然依赖于 API 的容器实现。如果例如怎么办?升级后的服务器实现仍然没有错误?这些问题是否会成为在 WAR 中包含特定库版本并独立运行容器的原因?但后来我想我会更好地切换到 tomcat。
  • 谢谢。我的意思是,只有在我的 war 文件中的所有实现(例如某些版本的 resteasy 或 jersey)作为显式依赖项的情况下才切换到 tomcat,那么就不需要使用应用程序服务器。我将把它写成问题中的注释
猜你喜欢
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 2022-12-28
  • 1970-01-01
  • 2017-05-25
  • 2011-02-18
  • 1970-01-01
相关资源
最近更新 更多