如何将专有的 Apache CXF 功能添加到 Open Liberty

How to add proprietary Apache CXF features to Open Liberty

我想使用专有的 Apache CXF 功能(文件上传的多部分处理),JAX-RS 2.1 规范中未涵盖该功能。将以下依赖项添加到我的 Jakarta EE 8 项目会导致奇怪的内部 Apache CXF NPE:

<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-frontend-jaxrs</artifactId>
  <version>3.3.4</version>
</dependency>

错误:

[INFO] java.lang.NullPointerException
[INFO] [WARNING ] Exception in handleFault on interceptor org.apache.cxf.jaxrs.interceptor.JAXRSDefaultFaultOutInterceptor@5e2be3a2
[INFO] org.apache.cxf.interceptor.Fault
[INFO] [ERROR   ] An unexpected error occurred during error handling. No further error processing will occur.
[INFO] org.apache.cxf.interceptor.Fault
[INFO] [ERROR   ] SRVE0777E: Exception thrown by application class 'org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor.filter:64'
[INFO] java.lang.NullPointerException
[INFO]  at org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor.filter(JAXRSBeanValidationInInterceptor.java:64)
[INFO]  at [internal classes]
[INFO] 
[INFO] [ERROR   ] SRVE0315E: An exception occurred: java.lang.Throwable: java.lang.NullPointerException
[INFO]  at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:5075)
[INFO]  at [internal classes]
[INFO] Caused by: java.lang.NullPointerException
[INFO]  at org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor.filter(JAXRSBeanValidationInInterceptor.java:64)
[INFO]  ... 1 more

根据我对这个问题的研究,我的理解是,应用程序无法访问内部 CXF 代码,因此范围 provided 将无法使用,并且使用我当前的解决方案(将扩展与.war 文件)导致类加载器问题。

我 运行 使用 Open Liberty 19.0.0.12 和 JDK 11

这是预期的行为。 Apache CXF 有许多超越 JAX-RS 规范的特性。在过去,传统的 WebSphere 遇到的问题是,他们使用开源产品来提供某些功能,公开该产品的所有 packages/classes,然后用户会使用它们。当用户想要引入与应用程序服务器中可用的不同版本或不同模块配置的开源产品时,问题就出现了。因此,用户必须将他们自己的产品版本与他们的应用程序或共享库打包在一起,并且必须求助于类加载技巧,如 parent-last,以避免加载该产品的 IBM 版本——这不可避免地会导致类加载问题,如 ClassCastExceptions。这种方法的另一个缺点是它把 IBM 逼到墙角——例如,如果开源产品不再受支持(即 Apache Wink),IBM 无法换掉开源产品来提供同样实现给定的替代方案规范.

Liberty 采用不同的方法。您可以使用 IBM 提供的功能,也可以将第三方库打包到您的应用程序(或共享库)中。这解决了上面列出的两个问题 - 但确实对您描述的场景有影响。

有几种不同的方法可以解决您的问题:

1) 使用 Open Liberty 打开问题(或对现有问题 +1)以正式支持您正在寻找的 CXF 专有功能。根据请求的功能,它可能需要为 API 使用不同的包名称,或者它可能涉及要启用的配置设置等。您可以在此处执行此操作:
https://github.com/OpenLiberty/open-liberty/issues

2) 从 server.xml 的功能管理器列表中删除 jaxrs-2.1 功能,并将 CXF 库与您的应用程序打包在一起。您还需要打包 JAX-RS API 库。

3) 您可以创建一个公开 CXF API 的用户功能 (https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_feat_develop.html)。这里需要注意的一点是,如果您公开 org.apache.cxf 包,然后 Liberty 将交换开源提供商(即切换到 Jersey 或 RestEasy),那么 org.apache.cxf 包将不再存在。这将有效地阻止您升级 Liberty 版本,直到您升级您的用户功能部件以打包 CXF 模块。选项 1 和 2 当然更适合未来。

希望对您有所帮助!安迪