diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 979e277bfcb8b..4bf6fa5fa4c13 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -212,7 +212,7 @@
2.18.0
0.8.12
1.2.1
- 4.2.1
+ 4.2.3
2.15.0
0.16.0
diff --git a/extensions/smallrye-reactive-messaging-pulsar/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/pulsar/deployment/SmallRyeReactiveMessagingPulsarProcessor.java b/extensions/smallrye-reactive-messaging-pulsar/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/pulsar/deployment/SmallRyeReactiveMessagingPulsarProcessor.java
index fbe2e163bcc14..581806fc90926 100644
--- a/extensions/smallrye-reactive-messaging-pulsar/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/pulsar/deployment/SmallRyeReactiveMessagingPulsarProcessor.java
+++ b/extensions/smallrye-reactive-messaging-pulsar/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/pulsar/deployment/SmallRyeReactiveMessagingPulsarProcessor.java
@@ -169,25 +169,32 @@ public NativeImageConfigBuildItem pulsarRuntimeInitialized(
// ReflectiveChannelFactory against the platform SocketChannel returned by
// EventLoopUtil. quarkus-netty registers only the NIO variants; register
// Epoll/KQueue/IOUring here so native image can find their no-arg
- // constructors at runtime. Revisit when bumping pulsar-client — if Pulsar
- // moves to non-reflective ChannelFactory factories, these can be removed.
- reflectiveClass.produce(ReflectiveClassBuildItem
- .builder("io.netty.channel.epoll.EpollSocketChannel",
- "io.netty.channel.epoll.EpollDatagramChannel",
- "io.netty.channel.kqueue.KQueueSocketChannel",
- "io.netty.channel.kqueue.KQueueDatagramChannel",
- "io.netty.incubator.channel.uring.IOUringSocketChannel",
- "io.netty.incubator.channel.uring.IOUringDatagramChannel")
- .constructors().build());
+ // constructors at runtime. These native transports are platform-specific
+ // and optional, so only register the ones actually on the classpath.
+ // Revisit when bumping pulsar-client — if Pulsar moves to non-reflective
+ // ChannelFactory factories, these can be removed.
+ String[] nettyTransportChannels = {
+ "io.netty.channel.epoll.EpollSocketChannel",
+ "io.netty.channel.epoll.EpollDatagramChannel",
+ "io.netty.channel.kqueue.KQueueSocketChannel",
+ "io.netty.channel.kqueue.KQueueDatagramChannel",
+ "io.netty.incubator.channel.uring.IOUringSocketChannel",
+ "io.netty.incubator.channel.uring.IOUringDatagramChannel"
+ };
+ for (String channel : nettyTransportChannels) {
+ if (QuarkusClassLoader.isClassPresentAtRuntime(channel)) {
+ reflectiveClass.produce(ReflectiveClassBuildItem.builder(channel).constructors().build());
+ }
+ }
Collection authPluginClasses = combinedIndex.getIndex()
- .getAllKnownImplementations(DotNames.PULSAR_AUTHENTICATION);
+ .getAllKnownImplementors(DotNames.PULSAR_AUTHENTICATION);
for (ClassInfo authPluginClass : authPluginClasses) {
reflectiveClass.produce(ReflectiveClassBuildItem.builder(authPluginClass.name().toString())
.constructors().build());
}
Collection sslFactoryClasses = combinedIndex.getIndex()
- .getAllKnownImplementations(DotNames.PULSAR_SSL_FACTORY);
+ .getAllKnownImplementors(DotNames.PULSAR_SSL_FACTORY);
for (ClassInfo sslFactoryClass : sslFactoryClasses) {
reflectiveClass.produce(ReflectiveClassBuildItem.builder(sslFactoryClass.name().toString())
.constructors().build());