Skip to content

UnsupportedOperationException in TlsConfigUtils when setting ALPN false #46652

@amusarra

Description

@amusarra

Description

The application is using the smallrye-amqp connector configured to use SSL/TLS connection through the TLS Registry configuration, as also reported in the Quarkus documentation.

# Configure the AMQP connection properties.
# Hostname, IP address, and port of the server RabbitMQ is running on
amqp-host=localhost
amqp-port=5671
amqp-use-ssl=true

# Username and password for the server RabbitMQ is running on
amqp-username=quarkus
amqp-password=quarkus

quarkus.tls.rabbitmq-tls-config.trust-store.pem.certs=certs/ca.crt
quarkus.tls.rabbitmq-tls-config.alpn=false

I encountered a java.lang.UnsupportedOperationException when using the TlsConfigUtils class to configure TLS options in my Quarkus project. The error occurs because the setUseAlpn method is called unconditionally, even when ALPN is disabled in the configuration.

I am currently blocked due to this incorrect behavior and cannot find a way to avoid this situation from the documentation.

Steps to Reproduce

  1. Set quarkus.tls.rabbitmq-tls-config.alpn=false in application.properties.
  2. Run the application.
  3. Observe the java.lang.UnsupportedOperationException in the logs.

Expected Behavior

The application should not call setUseAlpn when ALPN is disabled in the configuration, avoiding the UnsupportedOperationException.

Actual Behavior

The application throws a java.lang.UnsupportedOperationException because setUseAlpn is called unconditionally.

Image

Environment:

Quarkus version: 3.19.1
Java version: OpenJDK Runtime Environment Corretto-23.0.2.7.1 (build 23.0.2+7-FR)
Operating System: macOS 15.3.1 (24D70) (24.3.0 Darwin Kernel Version 24.3.0)

Additional Context

The issue occurs in the TlsConfigUtils class, which is part of the core of Quarkus. Here is the relevant code snippet:

public static void configure(TCPSSLOptions options, TlsConfiguration configuration) {
    options.setSsl(true);
    if (configuration.getTrustStoreOptions() != null) {
        options.setTrustOptions(configuration.getTrustStoreOptions());
    }

    if (configuration.getKeyStoreOptions() != null) {
        options.setKeyCertOptions(configuration.getKeyStoreOptions());
    }

    SSLOptions sslOptions = configuration.getSSLOptions();
    if (sslOptions != null) {
        options.setSslHandshakeTimeout(sslOptions.getSslHandshakeTimeout());
        options.setSslHandshakeTimeoutUnit(sslOptions.getSslHandshakeTimeoutUnit());
        for (String suite : sslOptions.getEnabledCipherSuites()) {
            options.addEnabledCipherSuite(suite);
        }
        for (Buffer buffer : sslOptions.getCrlValues()) {
            options.addCrlValue(buffer);
        }
        options.setEnabledSecureTransportProtocols(sslOptions.getEnabledSecureTransportProtocols());
        options.setUseAlpn(sslOptions.isUseAlpn());
    }
}
SRMSG00230: Unable to create the publisher or subscriber during initialization: java.lang.UnsupportedOperationException
	at io.vertx.proton.ProtonClientOptions.setUseAlpn(ProtonClientOptions.java:304)
	at io.vertx.proton.ProtonClientOptions.setUseAlpn(ProtonClientOptions.java:43)
	at io.quarkus.tls.runtime.config.TlsConfigUtils.configure(TlsConfigUtils.java:81)
	at io.quarkus.tls.runtime.config.TlsConfigUtils.configure(TlsConfigUtils.java:92)
	at io.quarkus.tls.runtime.config.TlsConfigUtils.configure(TlsConfigUtils.java:105)
	at io.quarkus.smallrye.reactivemessaging.amqp.runtime.AmqpClientConfigCustomizer.customize(AmqpClientConfigCustomizer.java:32)
	at io.quarkus.smallrye.reactivemessaging.amqp.runtime.AmqpClientConfigCustomizer.customize(AmqpClientConfigCustomizer.java:17)
	at io.quarkus.smallrye.reactivemessaging.amqp.runtime.AmqpClientConfigCustomizer_ClientProxy.customize(Unknown Source)
	at io.smallrye.reactive.messaging.providers.helpers.ConfigUtils.customize(ConfigUtils.java:21)
	at io.smallrye.reactive.messaging.amqp.AmqpClientHelper.createClient(AmqpClientHelper.java:35)
	at io.smallrye.reactive.messaging.amqp.AmqpConnector.getPublisher(AmqpConnector.java:224)
	at io.smallrye.reactive.messaging.amqp.AmqpConnector_Subclass.getPublisher$$superforward(Unknown Source)
	at io.smallrye.reactive.messaging.amqp.AmqpConnector_Subclass$$function$$7.apply(Unknown Source)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext$NextAroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:97)
	at io.quarkus.smallrye.reactivemessaging.runtime.devmode.DevModeSupportConnectorFactoryInterceptor.intercept(DevModeSupportConnectorFactoryInterceptor.java:53)
	at io.quarkus.smallrye.reactivemessaging.runtime.devmode.DevModeSupportConnectorFactoryInterceptor_Bean.intercept(Unknown Source)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:70)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
	at io.quarkus.smallrye.reactivemessaging.runtime.DuplicatedContextConnectorFactoryInterceptor.intercept(DuplicatedContextConnectorFactoryInterceptor.java:32)
	at io.quarkus.smallrye.reactivemessaging.runtime.DuplicatedContextConnectorFactoryInterceptor_Bean.intercept(Unknown Source)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
	at io.smallrye.reactive.messaging.amqp.AmqpConnector_Subclass.getPublisher(Unknown Source)
	at io.smallrye.reactive.messaging.amqp.AmqpConnector_ClientProxy.getPublisher(Unknown Source)
	at io.smallrye.reactive.messaging.providers.impl.ConfiguredChannelFactory.createPublisher(ConfiguredChannelFactory.java:208)
	at io.smallrye.reactive.messaging.providers.impl.ConfiguredChannelFactory.register(ConfiguredChannelFactory.java:146)
	at io.smallrye.reactive.messaging.providers.impl.ConfiguredChannelFactory.initialize(ConfiguredChannelFactory.java:115)
	at io.smallrye.reactive.messaging.providers.impl.ConfiguredChannelFactory_ClientProxy.initialize(Unknown Source)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:807)
	at io.smallrye.reactive.messaging.providers.extension.MediatorManager.start(MediatorManager.java:250)
	at io.smallrye.reactive.messaging.providers.extension.MediatorManager_ClientProxy.start(Unknown Source)
	at io.quarkus.smallrye.reactivemessaging.runtime.SmallRyeReactiveMessagingLifecycle.onApplicationStart(SmallRyeReactiveMessagingLifecycle.java:53)
	at io.quarkus.smallrye.reactivemessaging.runtime.SmallRyeReactiveMessagingLifecycle_Observer_onApplicationStart_qTrMuLFyQ1IvGfeSxRVitl6CCBQ.notify(Unknown Source)
	at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:365)
	at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:347)
	at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:81)
	at io.quarkus.arc.runtime.ArcRecorder.fireLifecycleEvent(ArcRecorder.java:163)
	at io.quarkus.arc.runtime.ArcRecorder.handleLifecycleEvents(ArcRecorder.java:114)
	at io.quarkus.runner.recorded.LifecycleEventsBuildStep$startupEvent1144526294.deploy_0(Unknown Source)
	at io.quarkus.runner.recorded.LifecycleEventsBuildStep$startupEvent1144526294.deploy(Unknown Source)
	at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:121)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:77)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:48)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:137)
	at io.quarkus.runner.GeneratedMain.main(Unknown Source)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:116)
	at java.base/java.lang.Thread.run(Thread.java:1575)

Here you can be found the example code https://github.com/amusarra/quarkus-quickstarts/tree/main/amqp-quickstart/amqp-quickstart-producer

Thank you for your assistance

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions