Open Liberty 21.0.0.12中的Jakarta EE 9.1支持和可配置的响应头文件

341 阅读12分钟

作为Open Liberty 21.0.0.12的一部分,现在可以支持Jakarta EE 9.1,以及可配置的响应头,这为响应头提供了更精细的控制!一些重要的错误修复也是这个版本的一部分。

Open Liberty21.0.0.12中:

除了添加到运行时中的新特性和功能外,我们还对指南进行了更新

使用21.0.0.12运行您的应用程序

如果您使用的是Maven,这里有坐标:

<dependency>
    <groupId>io.openliberty</groupId>
    <artifactId>openliberty-runtime</artifactId>
    <version>21.0.0.12</version>
    <type>zip</type>
</dependency>

或者对于Gradle:

dependencies {
    libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '[21.0.0.12,)'
}

或者如果你使用的是Docker:

FROM open-liberty

或者看一下我们的下载页面

Ask a question on Stack Overflow

支持Jakarta EE 9.1

jakarta ee

Jakarta EE 9.1支持现在可以在Open Liberty中使用了! 这项支持允许你使用Java 8、11或17运行Jakarta EE 9.1应用程序,并使用其他Open Liberty增值功能,这些功能已更新为支持Jakarta EE 9.1。 许多人通过我们的测试版和相应的博客关注我们交付Jakarta EE 9.1的进展,我们要感谢那些一路提供反馈的人。 如果你要为Jakarta EE 9.1设计一个新的应用程序,请确保使用jakarta 命名空间。 对于你想从Java EE(及其javax 命名空间)转移到Jakarta EE(及其jakarta 命名空间)的现有应用程序,我们建议尝试Eclipse Transformer,这个开源项目最初由Open Liberty团队的成员开发,然后贡献给Eclipse基金会。

随着Open Liberty中对RESTful Web Services 3.0(以前称为JAXRS)的支持,使用RESTful Web Services功能的应用程序的性能有了明显的改善。 这一性能改进是通过将我们的RESTful Web服务实现从Apache CXF转移到使用RestEasy实现的。 在这个新版本中,CDI被默认启用,JSON Binding被默认不启用,该功能在你的server.xml

任何带有API和/或SPI函数的自由功能,如果使用Jakarta EE APIs作为其方法签名的一部分,已经被更新,当在Jakarta EE 9.1中使用这些API/SPIs时,其包的版本将被重置为10.0。 当更新用户功能以使用Jakarta EE 9.1时,任何用于依赖这些包的用户功能的包将需要改变导入包的版本范围。

随着Jakarta EE 9.1的引入,Jakarta Enterprise Beans 4.0规范与之前的规范版本Enterprise JavaBeans (EJB) 3.2相比,包括以下几个小的变化:

  • 注意新的特性名称;所有相同的特性都存在,但特性名称的前缀从ejb 改为enterpriseBeans 。 例如,enterpriseBeansLite-4.0ejbLite-3.2 的新版本。

  • API包已经从javax.ejb 改为jakarta.ejb

  • @Schedule 注释现在是可重复的

  • 以下API方法已被删除:

    • javax.ejb.EJBContext.getCallerIdentity() → 使用getCallerPrincipal()

    • javax.ejb.EJBContext.getEnvironment() → 使用 中的查找JNDI java:comp/env

    • javax.ejb.EJBContext.isCallerInRole(java.security.Identity) → 使用isCallerInRole(String)

    • javax.ejb.SessionContext.getMessageContext() (与 一起删除)JAX-RPC

企业豆的所有其他功能与之前的规范版本(3.2)保持一致。

尽管Jakarta EE 9.1的许多功能只得到了版本更新,但大多数功能的名称也发生了变化。 下表列出了短名称和版本号都有变化的功能。要为Jakarta EE 9.1更新这些功能之一,你必须在你的server.xml 文件中同时改变功能的简称和版本号。

表1.Jakarta EE 9.1的功能更新,短名称和版本

Jakarta EE 9.1的功能名称Java EE/Jakarta EE 8的短名称和版本Jakarta EE 9.1 简称和版本
雅加达企业豆类

要全面了解变化的内容,请访问Jakarta EE 9.1功能更新页面。

要启用Jakarta EE 9.1的功能,请将相应的功能添加到你的server.xml 。你可以启用你想要的单个功能,也可以添加Jakarta EE 9.1的便利功能。 例如,要一次性启用所有Jakarta EE 9.1的功能,可以添加:

<featureManager>
    <feature>jakartaee-9.1</feature>
</featureManager>

或者你可以添加Web Profile便利功能来一次性启用所有Jakarta EE 9.1的Web Profile功能:

<featureManager>
    <feature>webProfile-9.1</feature>
</featureManager>

关于API和SPI的细节,请查看Jakarta EE 9.1 javadoc

可配置的响应头文件

你现在可以配置Open Liberty来修改响应头。 可用的配置选项允许添加头信息,覆盖现有的头信息,添加缺失的头信息,以及从HTTP端点提供的所有响应中删除不需要的头信息。这种配置提供了对响应头的更精细的控制,这为修改头提供了一个解决方案,而不需要改变现有的应用程序、过滤器或其他。

要使用可配置的响应头,首先要在server.xml 中定义一个新的元素,称为<headers> 。你可以为单个HTTP端点或所有端点一次性配置。

对单个HTTP端点进行配置:

<httpEndpoint id="defaultHttpEndpoint"
                  httpPort="9080"
                  httpsPort="9443">

    <headers>
        <add>foo:bar</add>
        <add>foo:bar2</add>
        <set>customHeader:customValue</set>
        <setIfMissing>X-Forwarded-Proto:https</setIfMissing>
        <remove>Via</remove>
    </headers>
</httpEndpoint>

为所有的HTTP端点配置:

<httpEndpoint id="defaultHttpEndpoint"
                  httpPort="9080"
                  httpsPort="9443"
                  headersRef="myHeadersID">
</httpEndpoint>

<httpEndpoint id="otherHttpEndpoint"
                  httpPort="9081"
                  httpsPort="9444"
                  headersRef="myHeadersID">
</httpEndpoint>

<headers id="myHeadersID">
    <add>foo:bar</add>
    <add>foo:bar2</add>
    <set>customHeader:customValue</set>
    <setIfMissing>X-Forwarded-Proto:https</setIfMissing>
    <remove>Via</remove>
</headers>

add 属性允许在一个响应中添加多个同名的头信息,类似于HttpServletResponse的addHeader API。类似地,set 属性类似于setHeader API,它将一个响应头设置为给定的名称和值。这将覆盖共享相同名称的现有头信息。setIfMissing 属性只在响应中没有配置的头信息时才会设置。最后,remove 属性将删除其名称与配置所定义的名称相匹配的任何响应头。

add,set, 和setIfMissing 属性的每个头条都可以作为独立的头条名称提供。也可以通过在每个头名称后面添加冒号: 来添加头值。然而,请注意,remove 属性只希望提供头名称,而不是头名称:值对。

正如在上面的例子中所看到的,配置<headers> 元素的一种方法是在它自己的add,set,setIfMissing, 或remove 属性中声明每个单独的头。除了这种配置外,头文件可以以逗号分隔的列表形式提供。

下面的server.xml配置在所需的配置属性中声明了各个头文件:

<headers>
    <add>foo:bar</add>
    <add>foo:bar2</add>
    <set>customHeader:customValue</set>
    <setIfMissing>X-Forwarded-Proto:https</setIfMissing>
    <remove>Via</remove>
</headers>

这种配置也可以用逗号分隔的列表来声明,例如:

<headers add="foo:bar, foo:bar2" set="customHeader:customValue" setIfMissing="X-Forwarded-Proto:https" remove="Via"/>

有三个与此功能的错误配置有关的警告信息。请注意,如果一个配置值被认为是错误配置的,它将不会被利用。此外,如果错误配置的值有一个非空的头名称,任何进一步的配置与此相同的名称也将被忽略。

只要头名称留空,第一条警告信息CWWKT0042W ,将被记录下来。虽然头的值是完全可选的,但该配置确实希望有一个非空的头的名称。

add 配置允许配置多个具有相同名称的头文件。然而,在任何其他配置属性中重复一个头的名称是不明确的。例如,考虑一下set 属性选项,它的目的是覆盖一个现有的共享声明头名称的头。如果set 配置中包含两个具有相同名称的头,那么就不清楚应该选择这两个值中的哪个。同样地,如果相同的头名称出现在两个或更多的配置中,也会出现同样的模糊性。因此,并且不包括add 配置中的重复,只要发现一个头名称被使用超过一次,将记录警告信息CWWKT0043W

第三条警告信息,CWWKT0044W ,如果一个已经被CWWKT0043W 警告信息标记为重复的头,继续被进一步的配置所利用,则会被记录下来。

警告信息描述。

CWWKT0042W:当'set'配置被解析时,发现了一个空的头名称。这个值被忽略。

CWWKT0043W :使用 配置在 [foo] 头中发现一个重复的头名称。所有对[foo]头的配置都被忽略。任何由remove、add、set或setIfMissing配置定义的头必须在所有配置中是唯一的。set

CWWKT0044W: 在 配置中发现了 [foo] 头,该头被标记为重复的头名称。[foo]头会被忽略。任何由 配置定义的头必须包含唯一的头名称。set set

摘要

Open Liberty现在提供了一种方法来控制特定HTTP端点的响应头。这些头信息可以被添加、配置为覆盖、仅在不存在的情况下被添加,或者从所有响应中完全删除。自己试试吧

此版本中修复的显著错误

我们花了一些时间来修复错误。下面的部分描述了在这个版本中解决的一些问题。如果你有兴趣,这里是21.0.0.12中修复的全部bug列表:

  • 由于Thread.getStackTrace的调用,eclipselink的吞吐量性能下降了

    我们发现了一个问题,对org.eclipse.persistence.internal.helper.ConcurrencyManager 类的改变导致eclipselink中的吞吐量性能下降了~75%。这种吞吐量的损失是由对Thread.getStackTrace() 的调用引起的。这种回归出现在 21.0.0.8 的jpa-2.2 和 21.0.0.9 的persistence-3.0 。现在这个问题已经通过删除getStackTrace() 的调用得到了解决。

  • MicroProfile OpenAPI 2.0在生成的文档中包括非公共字段

    以前,当为一个包含私有字段的类创建模式时,私有字段会被列在生成的OpenAPI文档中,例如:

    @Schema
    public class Example {
        private String field1;
        public String field2;
    }
    

    结果在:

      schemas:
        Example:
          type: object
          properties:
            field1:
              type: string
            field2:
              type: string
    

    该字段field1 ,因为它是私有的,所以不应该出现在生成的OpenAPI文档中。这个问题已经通过设置mp.openapi.extensions.smallrye.private-properties.enable 属性以默认禁用非公共属性而得到解决。

  • 服务器启动时跳过端口绑定

    以前,在一个极其罕见的情况下,配置的端口可能默默地不能绑定 - 阻止Liberty使用它们。这个问题是由负责延迟端口绑定的代码中的一个微妙的竞赛条件引起的,直到服务器准备好处理流量。

    在失败的情况下,端口开始的消息将不会被发出--例如,以下消息将被遗漏。

    CWWKO0219I: TCP Channel defaultHttpEndpoint has been started and is now listening for requests on host * (IPv4) port 9080.

    而下面的FFDC将被看到:

    Exception = java.lang.RuntimeException
    Source = com.ibm.ws.tcpchannel.internal.NBAcceptChannelSelector
    probeid = 254
    Stack Dump = java.lang.RuntimeException: java.nio.channels.NotYetBoundException
            at com.ibm.ws.tcpchannel.internal.NBAcceptChannelSelector.performRequest(NBAcceptChannelSelector.java:358)
            at com.ibm.ws.tcpchannel.internal.ChannelSelector.run(ChannelSelector.java:257)
            at java.base/java.lang.Thread.run(Thread.java:866)
    Caused by: java.nio.channels.NotYetBoundException
            at java.base/sun.nio.ch.ServerSocketChannelImpl.begin(ServerSocketChannelImpl.java:246)
            at java.base/sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:283)
            at com.ibm.ws.tcpchannel.internal.NBAcceptChannelSelector.performRequest(NBAcceptChannelSelector.java:278)
            ... 2 more
    

    这个问题现在已经被修复了,所以所有配置的端口都应该启动,或者如果有问题,应该记录一些有意义的错误信息。

  • 在server.xml更新的情况下,应用程序无法重新启动

    我们发现了一个问题,当安装了多个应用程序时,由于在服务器重新配置过程中出现了竞赛条件,应用程序将无法重新启动。这个问题发生在一个应用在另一个应用完成卸载之前启动。理论上这不应该是个问题--但是在这种情况下,这些应用程序共享一个VirtualHost配置对象,在这种情况下,一个应用程序更新父级VirtualHost作为其卸载过程的一部分,而另一个则进入无效状态。服务器日志将显示一个警告,如CWWKZ0020I: Application <app_name> not updated 。这个问题通过修复导致失败的竞赛条件得到了解决。

  • HTTP升级到WebSocket会导致quiesce错误

    当WebSocket连接启动时,它作为一个HTTP连接启动。以前,如果在HTTP和WebSocket连接之间的转换过程中发生错误,也就是已知的WebSocket升级,错误处理会忽略减少一个连接计数器,然后导致服务器认为在服务器停止期间有一个开放连接。 有两种情况会发生这些quiesce错误。

    • 当在HTTP和WebSocket连接的转换过程中发生读取错误时,错误处理忽略了对连接计数器的递减,从而导致服务器认为在服务器停止期间有一个开放连接。

    • 如果客户端在WebSocket连接被打开后立即关闭,原来的升级请求处理可能没有足够的时间在服务器上正确关闭。再一次,连接计数器未能递减,导致服务器认为在服务器停止期间有一个开放的连接。

      这个问题已经通过添加一个名为decrementNeeded 的新标志得到了解决,这有助于确保递减不会被忽视。

  • 确保ServletRequestListener#requestDestroyed始终被调用

    我们发现了一个错误,如果在启用appSecurity-x.0 的时候,在异步Servlet中发生了异常,那么ServletRequestListener#requestDestroyed 的调用就不会发生。要发生这个错误,必须满足两个条件:webContainer 属性deferServletRequestListenerDestroyOnError 为真,并且启用了appSecurity-x.0 功能。这个问题现在已经解决了。

  • JSP中与JDT内部类相关的ClassCastException

    Open Liberty 21.0.0.9引入了一个错误,即在JSP中某些类的查找会出现以下错误:

    Error 500: java.lang.ClassCastException: class org.eclipse.jdt.internal.compiler.lookup.PlainPackageBinding cannot be cast to class org.eclipse.jdt.internal.compiler.lookup.TypeBinding (org.eclipse.jdt.internal.compiler.lookup.PlainPackageBinding and org.eclipse.jdt.internal.compiler.lookup.TypeBinding are in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @3522bc53)
    

    这个问题现在已经被修复。

自上一版本以来新的和更新的指南

随着Open Liberty特性和功能的不断增长,我们将继续在openliberty.io上添加关于这些主题的新指南,以使其尽可能容易被采用。 现有的指南也会得到更新,以解决任何报告的错误/问题,保持其内容的时效性,并扩展其主题所涵盖的内容。

  • 创建一个多模块的应用程序

    • 此前,该指南展示了如何使用Maven和Open Liberty构建一个多模块的应用程序。 此次更新后,它现在还介绍了如何使用Liberty Maven插件在开发模式下开发一个多模块应用程序,而无需预先构建JAR和WAR文件。

立即获取Open Liberty 21.0.0.12

可通过Maven、Gradle、Docker以及可下载的存档获得。