I'd like to use a proprietary Apache CXF feature (Multipart handling for file upload), which is not covered in the JAX-RS 2.1 spec. Adding the following dependency to my Jakarta EE 8 project results in weird internal Apache CXF NPEs:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.3.4</version>
</dependency>
Errors:
[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
My understandings from my research for this problem are, that the application can't access the internal CXF code, so the scope provided
won't work and with my current solution (shipping the extension with the .war
file) it leads to classloader problems.
I'm running on Open Liberty 19.0.0.12 and JDK 11
This is the expected behavior. Apache CXF has many features that go beyond the JAX-RS specification. In the past traditional WebSphere has suffered from problems where they used an open source product to provide some functionality, exposed all of that product's packages/classes, and then users would use them. The problem starts when users then want to pull in a different version or different module configuration of the open source product than what is available in the application server. So then users must package their own version of the product with their app or in shared library, and must resort to classloading tricks like parent-last to avoid loading IBM's version of that product - and this inevitably leads to classloading problems like ClassCastExceptions. The other disadvantage of this approach is that it painted IBM in a corner - for example, if the open source product is no longer supported (i.e. Apache Wink), IBM could not swap out open source products to provide an alternative that also implements the given specification.
Liberty takes a different approach. You can use the IBM-provided features or you can package the third party libraries in your app (or shared library). This solves both of the problems listed above - but does have implications for the scenario you've described.
There are a few different approaches to resolving your issue:
1) Open an issue (or give a +1 to an existing issue) with Open Liberty to officially support the CXF proprietary feature(s) that you are looking for. Depending on the feature requested, it might require using a different package name for the API or it might involve a configuration setting to enable, etc. You can do that here:
https://github.com/OpenLiberty/open-liberty/issues
2) Remove the jaxrs-2.1
feature from the feature manager list in your server.xml, and package the CXF libraries with your app. You would also need to package the JAX-RS API libraries.
3) You could create a user feature ( https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_feat_develop.html ) that exposes the CXF APIs. One note of caution here is that if you expose the org.apache.cxf packages, and then Liberty were to swap open source providers (i.e. switch to Jersey or RestEasy), then the org.apache.cxf packages would no longer be there. That would effectively prevent you from upgrading Liberty versions until you upgraded your user feature to package the CXF modules. Options 1 and 2 are certainly more future-proof.
Hope this helps! Andy