Aggregated Quarkus CXF release notes 3.15.3 LTS → 3.20.2 LTS

This document may help when upgrading from the 3.15 LTS stream to 3.20 LTS stream.

New and noteworthy in Quarkus CXF

#1486 TLS Registry support

Quarkus TLS registry is an extension provided by Quarkus that centralizes the TLS configuration, making it easier to manage and maintain secure connections across your application.

io.quarkus:quarkus-tls-registry is a transitive dependency of io.quarkiverse.cxf:quarkus-cxf since Quarkus CXF 3.16.0, so you do not have to add it manually.

Quarkus TLS registry is the new recommended way of configuring trust stores, keystores and other TLS/SSL related settings in Quarkus CXF 3.16.0+:

application.properties
# Define a TLS configuration with name "hello-tls" (1)
quarkus.tls.hello-tls.trust-store.p12.path = client-truststore.pkcs12
quarkus.tls.hello-tls.trust-store.p12.password = client-truststore-password

# Basic client settings
quarkus.cxf.client.hello.client-endpoint-url = https://localhost:${quarkus.http.test-ssl-port}/services/hello
quarkus.cxf.client.hello.service-interface = io.quarkiverse.cxf.it.security.policy.HelloService

# Use "hello-tls" defined above for this client
quarkus.cxf.client.hello.tls-configuration-name = hello-tls
1 The referenced client-truststore.pkcs12 file has to be available either in the classpath or in the file system.

All client-related options provided by Quarkus TLS registry are supported for Vert.x based CXF clients.

Limitations with other clients

The named TLS configurations provided by TLS registry can be also used for CXF clients having http-conduit-factory set to URLConnectionHTTPConduitFactory, HttpClientHTTPConduitFactory or with Async CXF clients on top of Apache HttpClient 5. However, in those cases, the following TLS options are not supported and using them will lead to an exception at runtime:

Deprecated stores

The older way of configuring client trust stores and key stores is still supported, but deprecated since Quarkus CXF 3.16.0:

application.properties
# Deprecated way of setting the client trust store
quarkus.cxf.client.hello.trust-store-type = pkcs12
quarkus.cxf.client.hello.trust-store = client-truststore.pkcs12
quarkus.cxf.client.hello.trust-store-password = client-truststore-password

Vert.x HttpClient based HTTP Conduit is the new default

Vert.x HttpClient based HTTP Conduit was introduced in Quarkus CXF 3.13.0. Its usage was optional through setting the VertxHttpClientHTTPConduitFactory on either of the options quarkus.cxf.client."client-name".http-conduit-factory or quarkus.cxf.http-conduit-factory:

application.properties
# Before Quarkus CXF 3.16.0, VertxHttpClientHTTPConduitFactory had to be set explicitly
# Set the HTTPConduitFactory per-client
quarkus.cxf.client."client-name".http-conduit-factory = VertxHttpClientHTTPConduitFactory
# Set the HTTPConduitFactory globally
quarkus.cxf.http-conduit-factory = VertxHttpClientHTTPConduitFactory

Since then, it went through some improvements and testing so that we are now confident to make it default.

The main motivations for using Vert.x HttpClient based HTTP Conduit as a default are as follows:

  • Support for HTTP/2

  • Seamless integration with Quarkus, especially in the areas of worker thread poolling and SSL/TLS configuration.

Force the old default

Before this change, the effective default was URLConnectionHTTPConduitFactory. It is still supported and tested regularly.

You can get back to the old default in any one of three ways:

  1. Set the QUARKUS_CXF_DEFAULT_HTTP_CONDUIT_FACTORY environment variable to URLConnectionHTTPConduitFactory

  2. Set the global quarkus.cxf.http-conduit-factory option to URLConnectionHTTPConduitFactory

  3. Set the per client quarkus.cxf.client."client-name".http-conduit-factory option to URLConnectionHTTPConduitFactory

Hostname verifiers not supported in combination with VertxHttpClientHTTPConduitFactory

Since Quarkus CXF 3.16.0, setting quarkus.cxf.client."client-name".hostname-verifier together with using the default VertxHttpClientHTTPConduitFactory leads to an exception at runtime.

The AllowAllHostnameVerifier value of that option can be replaced by using a named TLS configuration with hostname-verification-algorithm set to NONE.

Here is an example: if your configuration before Quarkus CXF 3.16.0 was as follows

application.properties
# A configuration that worked before Quarkus CXF 3.16.0
quarkus.cxf.client.helloAllowAll.client-endpoint-url = https://localhost:8444/services/hello
quarkus.cxf.client.helloAllowAll.service-interface = io.quarkiverse.cxf.it.security.policy.HelloService
quarkus.cxf.client.helloAllowAll.trust-store = client-truststore.pkcs12
quarkus.cxf.client.helloAllowAll.trust-store-password = secret
quarkus.cxf.client.helloAllowAll.hostname-verifier = AllowAllHostnameVerifier

then an equivalent configuration for Quarkus CXF 3.16.0+ is

application.properties
# An equivalent configuration for Quarkus CXF 3.16.0+
quarkus.tls.helloAllowAll.trust-store.p12.path = client-truststore.pkcs12
quarkus.tls.helloAllowAll.trust-store.p12.password = secret
quarkus.tls.helloAllowAll.hostname-verification-algorithm = NONE
quarkus.cxf.client.helloAllowAll.client-endpoint-url = https://localhost:8444/services/hello
quarkus.cxf.client.helloAllowAll.service-interface = io.quarkiverse.cxf.it.security.policy.HelloService
quarkus.cxf.client.helloAllowAll.tls-configuration-name = helloAllowAll

#1447 Support asynchronous mode with VertxHttpClientHTTPConduit

Before Quarkus CXF 3.17.0, CXF clients based on VertxHttpClientHTTPConduit could only be called synchronously:

@CXFClient("hello")
HelloService hello;

String callHello() {
    // Synchronous CXF client call
    hello.hello("Joe");
}

Quarkus CXF 3.17.0 introduces the asynchronous mode for VertxHttpClientHTTPConduit-based clients:

import io.smallrye.mutiny.Uni;

@CXFClient("hello")
HelloService hello;

Uni<String> callHelloAsync() {
    return Uni.createFrom()
            // Asynchronous CXF client call returning java.util.concurrent.Future
            .future(hello.helloAsync("Joe"))
            .map(HelloResponse::getReturn);
}

This works much like with the existing Apache HttpClient 5 Async HTTP Transport. The main difference is that you do not need to add (now deprecated) io.quarkiverse.cxf:quarkus-cxf-rt-transports-http-hc5 dependency to your application anymore.

You still need to generate the async methods using the embedded wsdl2java tool.

Check the Asynchronous client page for more information.

#1609 Support HTTP redirects with VertxHttpClientHTTPConduit

Before Quarkus CXF 3.17.0, the VertxHttpClientHTTPConduit-based CXF clients were not following HTTP redirects (HTTP status codes 301, 302, 303 and 307 with Location response header) even if quarkus.cxf.client."client-name".auto-redirect was enabled for the given client.

Quarkus CXF 3.17.0 adds this functionality along with the proper support for quarkus.cxf.client."client-name".max-retransmits.

A new configuration property quarkus.cxf.client."client-name".redirect-relative-uri was introduced. It is equivalent to setting http.redirect.relative.uri property on the CXF client request context as already supported by CXF.

#1639 Add quarkus.cxf.client."client-name".max-same-uri configuration option

Check quarkus.cxf.client."client-name".max-same-uri's documentation for more information.

Special thanks to @dcheng1248 for the contribution.

#1628 Support offloading the request data to disk with VertxHttpClientHTTPConduit

Quarkus CXF 3.17.0, added support for redirects with VertxHttpClientHTTPConduit. It included some basic in-memory caching of the request body for the sake of retransmission. Since Quarkus CXF 3.18.0, the VertxHttpClientHTTPConduit is able to offload the data to disk in case the size of the body surpasses some configurable threshold. Check the documentation of the following new configuration options to learn how the new feature works:

The above configuration options also works for URLConnectionHTTPConduit.

#1616 Support authorization retransmits in VertxHttpClientHTTPConduit

Before Quarkus CXF 3.20.0, when a remote service responded with 401 Unauthorized or 407 Proxy Authentication Required, clients backed by VertxHttpClientHTTPConduit would simply fail and the only possible workaround was to use some other HTTP conduit, such as URLConnectionHTTPConduit.

Since Quarkus CXF 3.20.0, VertxHttpClientHTTPConduit handles 401 and 407 status codes properly by sending a new request with an Authorization header value derived from one or more of following options:

#1680 Introduce quarkus.cxf.client.tls-configuration-name to set TLS options for all CXF clients

Before Quarkus CXF 3.19.0, it was only possible to configure trust stores and key stores per CXF client via quarkus.cxf.client."client-name".tls-configuration-name or (now deprecated) quarkus.cxf.client."client-name".key-store* and quarkus.cxf.client."client-name".trust-store* options.

In cases with multiple clients, this configuration could get verbose.

Since Quarkus CXF 3.19.0, it is possible to set the trust stores and key stores for all clients using the quarkus.cxf.client.tls-configuration-name option.

Bugfixes

#1697 Native build fails when using quarkus-cxf-integration-tracing-opentelemetry and quarkus-jdbc-oracle

Before Quarkus CXF 3.19.0, combining quarkus-jdbc-oracle with quarkus-cxf-integration-tracing-opentelemetry or quarkus-cxf-rt-ws-rm in a single application resulted in an error during the build of native image as follows:

org.graalvm.compiler.debug.GraalError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException:
Detected a MBean server in the image heap. This is currently not supported, but could be changed in the future.
Management beans are registered in many global caches that would need to be cleared and properly re-built at image build time.
Class of disallowed object: com.sun.jmx.mbeanserver.JmxMBeanServer

We have fixed this in Quarkus CXF 3.19.0.

JMX features are still not supported in native mode.

#1326 CXF-9003 Name clash between Service methods with the same name in one Java package

For each service method, several ancillary classes are generated at build time. These may represent a request or a response of an operation. So, for com.acme.HelloService.hello() method at least two classes com.acme.jaxws_asm.Hello and com.acme.jaxws_asm.HelloResponse would be generated. Before Quarkus CXF 3.20.0 and CXF 4.1.1, the name of the service class was not taken into account. Therefore, when there were multiple service interfaces containing methods with the same name in a single Java package, then the names for their ancillary classes would clash. This would mean that only one set of those classes, suiting only one of those services was stored in the application. At runtime, the following error message may appear in the application log:

java.lang.IllegalArgumentException: argument type mismatch
     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.base/java.lang.reflect.Method.invoke(Method.java:568)
     at org.apache.cxf.databinding.AbstractWrapperHelper.createWrapperObject(AbstractWrapperHelper.java:114)
     at org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:91)
     at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
     at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:441)
     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:356)
     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314)
     at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
     at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
     at jdk.proxy6/jdk.proxy6.$Proxy132.hello(Unknown Source)

The problem was fixed in CXF 4.1.1 and Quarkus CXF 3.20.0. Now, the name of the service class is taken into account. So for the above example, the names of the generated classes would be com.acme.jaxws_asm.helloservice.Hello and com.acme.jaxws_asm.helloservice.HelloResponse respectively.

Deprecations

#1633 HttpClientHTTPConduitFactory value of *.http-conduit-factory deprecated

The HttpClientHTTPConduitFactory value of quarkus.cxf.http-conduit-factory and quarkus.cxf.client."client-name".http-conduit-factory existed since their inception in Quarkus CXF 2.3.0.

HttpClientHTTPConduit never gained any real traction within Quarkus CXF. When CXF started using it as a default, we were forced to introduce our own default (URLConnectionHTTPConduitFactory) to avoid bugs like #992, CXF-8885, CXF-8951, CXF-8946, CXF-8903 and possibly others. Now that we have VertxHttpClientHTTPConduit, which we can support very well on Quarkus, there are no more reasons for us to spend our resources on HttpClientHTTPConduit.

HttpClientHTTPConduitFactory was marked as deprecated in our documentation and we added some warnings on application startup for folks still using it.

#1632 io.quarkiverse.cxf:quarkus-cxf-rt-transports-http-hc5 deprecated

The io.quarkiverse.cxf:quarkus-cxf-rt-transports-http-hc5 extension is deprecated since Quarkus CXF 3.19.0 and it is scheduled for removal in 3.21.0. Use the asynchronous mode of VertxHttpClientHTTPConduit instead.

This is a part of our efforts to support only a single HTTP Conduit based on Vert.x HttpClient in the future.