Support arbitrary keystore/truststore types via 'other' config#53491
Support arbitrary keystore/truststore types via 'other' config#53491cescoffier wants to merge 1 commit intoquarkusio:mainfrom
Conversation
Add a new 'other' config group to KeyStoreConfig and TrustStoreConfig, allowing users to configure arbitrary keystore types (e.g., BCFKS) via quarkus.tls.key-store.other.type=<type> without writing code. The standard fallback uses KeyStore.getInstance(type, provider) to load the store from a file. For types needing custom loading logic, users can provide a KeyStoreFactory or TrustStoreFactory CDI bean annotated with @Identifier matching the type value. Resolves: quarkusio#50304 Co-authored-by: Samuel Nelson <samuel.nelson@elastic.co>
Status for workflow
|
|
🎊 PR Preview eb57f6d has been successfully built and deployed to https://quarkus-pr-main-53491-preview.surge.sh/version/main/guides/
|
Status for workflow
|
| Status | Name | Step | Failures | Logs | Raw logs | Build scan |
|---|---|---|---|---|---|---|
| ✔️ | Gradle Tests - JDK 25 | Logs | Raw logs | 🚧 | ||
| ❌ | Gradle Tests - JDK 17 Windows | Build |
Logs | Raw logs | 🚧 | |
| ❌ | JVM Integration Tests - JDK 17 | Build |
Failures | Logs | Raw logs | 🚧 |
| ✔️ | JVM Integration Tests - JDK 17 Windows | Logs | Raw logs | 🚧 | ||
| ✔️ | JVM Integration Tests - JDK 21 | Logs | Raw logs | 🚧 | ||
| ✔️ | JVM Integration Tests - JDK 25 | Logs | Raw logs | 🚧 | ||
| ✔️ | JVM Integration Tests - JDK 25 Semeru | Logs | Raw logs | 🚧 |
Full information is available in the Build summary check run.
Failures
⚙️ JVM Integration Tests - JDK 17 #
- Failing: integration-tests/smallrye-stork-consul-registration-prod-mode
📦 integration-tests/smallrye-stork-consul-registration-prod-mode
❌ org.acme.DeregistrationTest.testDeregistrationAfterShutdown line 50 - History - More details - Source on GitHub
Details
org.awaitility.core.ConditionTimeoutException:
Assertion condition defined as a Lambda expression in org.acme.DeregistrationTest 1 expectation failed.
Expected status code <404> but was <200>.
within 20 seconds.
at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:119)
at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:31)
at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1160)
Flaky tests - Develocity
⚙️ JVM Tests - JDK 21
📦 extensions/websockets-next/deployment
❌ io.quarkus.websockets.next.test.telemetry.MicrometerWebSocketsOnTextMessageTest.testClientEndpoint_MultiTextReceived_MultiTextSent - History
Assertion condition defined as a Lambda expression in io.quarkus.websockets.next.test.telemetry.MetricsAsserter 1 expectation failed. Response body doesn't match expectation. Expected: Key 'quarkus_websockets_server_connections_opened_total' with value '21' and direction 'null' Actual: \# TYPE jvm_threads_daemon_threads gauge \# HELP jvm_threads_daemon_threads The current number of live daemon threads-org.awaitility.core.ConditionTimeoutException
Details
org.awaitility.core.ConditionTimeoutException:
Assertion condition defined as a Lambda expression in io.quarkus.websockets.next.test.telemetry.MetricsAsserter 1 expectation failed.
Response body doesn't match expectation.
Expected: Key 'quarkus_websockets_server_connections_opened_total' with value '21' and direction 'null'
Actual: # TYPE jvm_threads_daemon_threads gauge
# HELP jvm_threads_daemon_threads The current number of live daemon threads
jvm_threads_daemon_threads 15.0
# TYPE jvm_threads_peak_threads gauge
❌ io.quarkus.websockets.next.test.telemetry.MicrometerWebSocketsOnTextMessageTest.testClientEndpoint_PathParam - History
Assertion condition defined as a Lambda expression in io.quarkus.websockets.next.test.telemetry.MetricsAsserter 1 expectation failed. Response body doesn't match expectation. Expected: Key 'quarkus_websockets_server_connections_opened_total' with value '23' and direction 'null' Actual: \# TYPE jvm_threads_daemon_threads gauge \# HELP jvm_threads_daemon_threads The current number of live daemon threads-org.awaitility.core.ConditionTimeoutException
Details
org.awaitility.core.ConditionTimeoutException:
Assertion condition defined as a Lambda expression in io.quarkus.websockets.next.test.telemetry.MetricsAsserter 1 expectation failed.
Response body doesn't match expectation.
Expected: Key 'quarkus_websockets_server_connections_opened_total' with value '23' and direction 'null'
Actual: # TYPE jvm_threads_daemon_threads gauge
# HELP jvm_threads_daemon_threads The current number of live daemon threads
jvm_threads_daemon_threads 14.0
# TYPE jvm_threads_peak_threads gauge
❌ io.quarkus.websockets.next.test.telemetry.MicrometerWebSocketsOnTextMessageTest.testServerEndpoint_PathParams_ResponseFromOnOpenMethod - History
Assertion condition defined as a Lambda expression in io.quarkus.websockets.next.test.telemetry.MetricsAsserter 1 expectation failed. Response body doesn't match expectation. Expected: Key 'quarkus_websockets_server_connections_opened_total' with value '22' and direction 'null' Actual: \# TYPE jvm_threads_daemon_threads gauge \# HELP jvm_threads_daemon_threads The current number of live daemon threads-org.awaitility.core.ConditionTimeoutException
Details
org.awaitility.core.ConditionTimeoutException:
Assertion condition defined as a Lambda expression in io.quarkus.websockets.next.test.telemetry.MetricsAsserter 1 expectation failed.
Response body doesn't match expectation.
Expected: Key 'quarkus_websockets_server_connections_opened_total' with value '22' and direction 'null'
Actual: # TYPE jvm_threads_daemon_threads gauge
# HELP jvm_threads_daemon_threads The current number of live daemon threads
jvm_threads_daemon_threads 14.0
# TYPE jvm_threads_peak_threads gauge
❌ io.quarkus.websockets.next.test.telemetry.MicrometerWebSocketsOnTextMessageTest.testServerEndpoint_broadcasting - History
Assertion condition defined as a Lambda expression in io.quarkus.websockets.next.test.telemetry.AbstractWebSocketsOnMessageTest Expected 1, got 0 ==> expected: <true> but was: <false> within 5 seconds.-org.awaitility.core.ConditionTimeoutException
Details
org.awaitility.core.ConditionTimeoutException: Assertion condition defined as a Lambda expression in io.quarkus.websockets.next.test.telemetry.AbstractWebSocketsOnMessageTest Expected 1, got 0 ==> expected: <true> but was: <false> within 5 seconds.
at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:119)
at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:31)
at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1160)
at org.awaitility.core.ConditionFactory.untilAsserted(ConditionFactory.java:790)
at io.quarkus.websockets.next.test.telemetry.AbstractWebSocketsOnMessageTest.testServerEndpoint_broadcasting(AbstractWebSocketsOnMessageTest.java:414)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
⚙️ JVM Tests - JDK 25
📦 extensions/scheduler/deployment
❌ io.quarkus.scheduler.test.PausedSchedulerTest.testSchedulerPauseResume - History
expected: <false> but was: <true>-org.opentest4j.AssertionFailedError
Details
org.opentest4j.AssertionFailedError: expected: <false> but was: <true>
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:158)
at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:139)
at org.junit.jupiter.api.AssertFalse.failNotFalse(AssertFalse.java:69)
at org.junit.jupiter.api.AssertFalse.assertFalse(AssertFalse.java:41)
at org.junit.jupiter.api.AssertFalse.assertFalse(AssertFalse.java:35)
at org.junit.jupiter.api.Assertions.assertFalse(Assertions.java:246)
at io.quarkus.scheduler.test.PausedSchedulerTest.testSchedulerPauseResume(PausedSchedulerTest.java:47)
📦 extensions/vertx-http/deployment
❌ io.quarkus.vertx.http.filters.GracefulShutdownFilterTest.test - History
Timeout waiting for response-java.lang.RuntimeException
Details
java.lang.RuntimeException: Timeout waiting for response
at io.quarkus.vertx.http.filters.GracefulShutdownFilterTest.testWithVertxHttpClientAndHttp2AfterShutdown(GracefulShutdownFilterTest.java:85)
at io.quarkus.vertx.http.filters.GracefulShutdownFilterTest.test(GracefulShutdownFilterTest.java:59)
⚙️ JVM Tests - JDK 17 Windows
📦 extensions/quartz/deployment
❌ io.quarkus.quartz.test.PausedSchedulerTest.testSchedulerPauseResume - History
expected: <false> but was: <true>-org.opentest4j.AssertionFailedError
Details
org.opentest4j.AssertionFailedError: expected: <false> but was: <true>
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:158)
at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:139)
at org.junit.jupiter.api.AssertFalse.failNotFalse(AssertFalse.java:69)
at org.junit.jupiter.api.AssertFalse.assertFalse(AssertFalse.java:41)
at org.junit.jupiter.api.AssertFalse.assertFalse(AssertFalse.java:35)
at org.junit.jupiter.api.Assertions.assertFalse(Assertions.java:246)
at io.quarkus.quartz.test.PausedSchedulerTest.testSchedulerPauseResume(PausedSchedulerTest.java:47)
⚙️ JVM Integration Tests - JDK 25 Semeru
📦 integration-tests/compose-devservices
❌ io.quarkus.it.compose.devservices.rabbitmq.RabbitmqTest.test - History
Read timed out-java.net.SocketTimeoutException
Details
java.net.SocketTimeoutException: Read timed out
at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:277)
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:302)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:354)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:798)
at java.base/java.net.Socket$SocketInputStream.implRead(Socket.java:974)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:964)
at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:161)
| @@ -0,0 +1,31 @@ | |||
| package io.quarkus.tls.runtime; | |||
There was a problem hiding this comment.
Is runtime the right package? It used to be used for internal stuff, but maybe the ADR changed that?
Same question for the other inferface.
There was a problem hiding this comment.
Very good point... I will check.

This PR is the continuation of #52582.
Add a new 'other' config group to KeyStoreConfig and TrustStoreConfig, allowing users to configure arbitrary keystore types (e.g., BCFKS) via
quarkus.tls.key-store.other.type=<type>without writing code.The standard fallback uses KeyStore.getInstance(type, provider) to load the store from a file. For types that need custom loading logic, users can provide a KeyStoreFactory or TrustStoreFactory CDI bean annotated with
@Identifierthat matches the type value.Co-Authored by @s-nel