Jakarta-ee应用程序最佳实践:应该使用特定于容器的实现吗



我正在构建我的第一个雅加达ee 8应用程序。事实上,我来自Spring Framework背景,所以我专注于关键的差异和最佳实践。我读到Glassfish、Wildfly、JBoss-EAP等提供了雅加达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?

我将用下面的例子使这个问题更加具体。

我使用helloworld JAX-RSWebservice创建了两个版本的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。

在上运行上述应用程序

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

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

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

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

作为最佳实践,只需从雅加达EE API依赖性开始:

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

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

JAX-RS2.1规范涵盖了很多特性,这些特性很可能已经足够了。

可能存在一些边缘情况,其中规范没有提供易于使用的解决方案,并且您可能希望包括特定于供应商的实现,这些实现不是正式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的导入,您就使用了规范之外的东西。

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

更新:

如果升级后的服务器实现仍然没有bug,该怎么办?

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

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

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