You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2020/11/16 09:37:29 UTC

[camel-quarkus] branch master updated: Kudu: unshade and remove embedded netty and use quarkus-netty instead #1907

This is an automated email from the ASF dual-hosted git repository.

ppalaga pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/master by this push:
     new 3f784b0  Kudu: unshade and remove embedded netty and use quarkus-netty instead #1907
3f784b0 is described below

commit 3f784b0c1da00ce4f8978063ff7588f7ffe6a8d2
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Fri Nov 13 16:37:33 2020 +0100

    Kudu: unshade and remove embedded netty and use quarkus-netty instead
    #1907
---
 extensions/kudu/client/pom.xml                     |  97 +++++
 extensions/kudu/deployment/pom.xml                 |   4 +
 .../kudu/deployment/JBossNettyLoggerFactory.java   | 197 ---------
 .../component/kudu/deployment/KuduProcessor.java   | 160 --------
 extensions/kudu/pom.xml                            |   1 +
 extensions/kudu/runtime/pom.xml                    |  14 +
 .../component/kudu/graal/EmptyByteBufStub.java     |  53 ---
 .../component/kudu/graal/NettySubstitutions.java   | 453 ---------------------
 .../component/kudu/graal/ZLibSubstitutions.java    |  88 ----
 pom.xml                                            |   1 +
 poms/bom/pom.xml                                   |  10 +
 11 files changed, 127 insertions(+), 951 deletions(-)

diff --git a/extensions/kudu/client/pom.xml b/extensions/kudu/client/pom.xml
new file mode 100644
index 0000000..c251f6c
--- /dev/null
+++ b/extensions/kudu/client/pom.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-kudu-parent</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-kudu-client</artifactId>
+    <name>Camel Quarkus :: Kudu :: Client</name>
+
+    <description>org.apache.kudu:kudu-client with netty package relocations reverted and netty classes stripped away
+        so that camel-quarkus-kudu can use quarkus-netty as a replacement</description>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-bom</artifactId>
+                <version>${project.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.kudu</groupId>
+            <artifactId>kudu-client</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>transform-kudu-client</id>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <phase>package</phase>
+                        <configuration>
+                            <artifactSet>
+                                <excludes>
+                                    <exclude>com.stumbleupon:async</exclude>
+                                    <exclude>org.slf4j:slf4j-api</exclude>
+                                </excludes>
+                            </artifactSet>
+                            <relocations>
+                                <relocation>
+                                    <pattern>org.apache.kudu.shaded.io.netty</pattern>
+                                    <shadedPattern>io.netty</shadedPattern>
+                                </relocation>
+                            </relocations>
+                            <filters>
+                                <filter>
+                                    <artifact>org.apache.kudu:kudu-client</artifact>
+                                    <excludes>
+                                        <exclude>META-INF/native-image/**</exclude>
+                                        <exclude>org/apache/kudu/shaded/io/netty/**</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                            <createSourcesJar>true</createSourcesJar>
+                            <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/extensions/kudu/deployment/pom.xml b/extensions/kudu/deployment/pom.xml
index b972962..50c52dd 100644
--- a/extensions/kudu/deployment/pom.xml
+++ b/extensions/kudu/deployment/pom.xml
@@ -35,6 +35,10 @@
             <artifactId>camel-quarkus-core-deployment</artifactId>
         </dependency>
         <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-netty-deployment</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-kudu</artifactId>
         </dependency>
diff --git a/extensions/kudu/deployment/src/main/java/org/apache/camel/quarkus/component/kudu/deployment/JBossNettyLoggerFactory.java b/extensions/kudu/deployment/src/main/java/org/apache/camel/quarkus/component/kudu/deployment/JBossNettyLoggerFactory.java
deleted file mode 100644
index 0e2520b..0000000
--- a/extensions/kudu/deployment/src/main/java/org/apache/camel/quarkus/component/kudu/deployment/JBossNettyLoggerFactory.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.quarkus.component.kudu.deployment;
-
-import org.apache.kudu.shaded.io.netty.util.internal.logging.AbstractInternalLogger;
-import org.apache.kudu.shaded.io.netty.util.internal.logging.InternalLogger;
-import org.apache.kudu.shaded.io.netty.util.internal.logging.InternalLoggerFactory;
-import org.jboss.logging.Logger;
-
-/**
- * Adapted from
- * https://github.com/quarkusio/quarkus/blob/master/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/JBossNettyLoggerFactory.java
- *
- */
-public class JBossNettyLoggerFactory extends InternalLoggerFactory {
-
-    @Override
-    protected InternalLogger newInstance(String name) {
-        return new JBossNettyInternalLogger(name);
-    }
-
-    private static final class JBossNettyInternalLogger extends AbstractInternalLogger {
-
-        final Logger log;
-
-        JBossNettyInternalLogger(String name) {
-            super(name);
-            log = Logger.getLogger(name);
-        }
-
-        @Override
-        public boolean isTraceEnabled() {
-            return log.isTraceEnabled();
-        }
-
-        @Override
-        public void trace(String msg) {
-            log.trace(msg);
-        }
-
-        @Override
-        public void trace(String format, Object arg) {
-            log.tracef(format, arg);
-        }
-
-        @Override
-        public void trace(String format, Object argA, Object argB) {
-            log.tracef(format, argA, argB);
-        }
-
-        @Override
-        public void trace(String format, Object... arguments) {
-            log.tracef(format, arguments);
-        }
-
-        @Override
-        public void trace(String msg, Throwable t) {
-            log.trace(msg, t);
-        }
-
-        @Override
-        public boolean isDebugEnabled() {
-            return log.isDebugEnabled();
-        }
-
-        @Override
-        public void debug(String msg) {
-            log.debug(msg);
-        }
-
-        @Override
-        public void debug(String format, Object arg) {
-            log.debugf(format, arg);
-        }
-
-        @Override
-        public void debug(String format, Object argA, Object argB) {
-            log.debugf(format, argA, argB);
-        }
-
-        @Override
-        public void debug(String format, Object... arguments) {
-            log.debugf(format, arguments);
-        }
-
-        @Override
-        public void debug(String msg, Throwable t) {
-            log.debug(msg, t);
-        }
-
-        @Override
-        public boolean isInfoEnabled() {
-            return log.isInfoEnabled();
-        }
-
-        @Override
-        public void info(String msg) {
-            log.info(msg);
-        }
-
-        @Override
-        public void info(String format, Object arg) {
-            log.infof(format, arg);
-        }
-
-        @Override
-        public void info(String format, Object argA, Object argB) {
-            log.infof(format, argA, argB);
-        }
-
-        @Override
-        public void info(String format, Object... arguments) {
-            log.infof(format, arguments);
-        }
-
-        @Override
-        public void info(String msg, Throwable t) {
-            log.info(msg, t);
-        }
-
-        @Override
-        public boolean isWarnEnabled() {
-            return log.isEnabled(Logger.Level.WARN);
-        }
-
-        @Override
-        public void warn(String msg) {
-            log.warn(msg);
-        }
-
-        @Override
-        public void warn(String format, Object arg) {
-            log.warnf(format, arg);
-        }
-
-        @Override
-        public void warn(String format, Object... arguments) {
-            log.warnf(format, arguments);
-        }
-
-        @Override
-        public void warn(String format, Object argA, Object argB) {
-            log.warnf(format, argA, argB);
-        }
-
-        @Override
-        public void warn(String msg, Throwable t) {
-            log.warn(msg, t);
-        }
-
-        @Override
-        public boolean isErrorEnabled() {
-            return log.isEnabled(Logger.Level.ERROR);
-        }
-
-        @Override
-        public void error(String msg) {
-            log.error(msg);
-        }
-
-        @Override
-        public void error(String format, Object arg) {
-            log.errorf(format, arg);
-        }
-
-        @Override
-        public void error(String format, Object argA, Object argB) {
-            log.errorf(format, argA, argB);
-        }
-
-        @Override
-        public void error(String format, Object... arguments) {
-            log.errorf(format, arguments);
-        }
-
-        @Override
-        public void error(String msg, Throwable t) {
-            log.error(msg, t);
-        }
-
-    }
-
-}
diff --git a/extensions/kudu/deployment/src/main/java/org/apache/camel/quarkus/component/kudu/deployment/KuduProcessor.java b/extensions/kudu/deployment/src/main/java/org/apache/camel/quarkus/component/kudu/deployment/KuduProcessor.java
index 56dee82..cab0cc1 100644
--- a/extensions/kudu/deployment/src/main/java/org/apache/camel/quarkus/component/kudu/deployment/KuduProcessor.java
+++ b/extensions/kudu/deployment/src/main/java/org/apache/camel/quarkus/component/kudu/deployment/KuduProcessor.java
@@ -16,27 +16,13 @@
  */
 package org.apache.camel.quarkus.component.kudu.deployment;
 
-import java.util.Arrays;
-import java.util.List;
-
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
 import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.UnsafeAccessedFieldBuildItem;
-import org.apache.camel.quarkus.component.kudu.graal.EmptyByteBufStub;
-import org.apache.kudu.shaded.io.netty.util.internal.logging.InternalLoggerFactory;
-import org.jboss.logging.Logger;
 
 class KuduProcessor {
-    private static final Logger LOGGER = Logger.getLogger(KuduProcessor.class);
-    static {
-        InternalLoggerFactory.setDefaultFactory(new JBossNettyLoggerFactory());
-    }
 
     private static final String FEATURE = "camel-kudu";
 
@@ -57,150 +43,4 @@ class KuduProcessor {
                 "org.apache.kudu.tserver.Tserver$ResourceMetricsPB$Builder"));
     }
 
-    /*
-     * Adapted from https://github.com/quarkusio/quarkus/blob/master/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java
-     */
-    @BuildStep
-    void netty(
-            BuildProducer<NativeImageConfigBuildItem> nativeImageConfig,
-            BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
-
-        reflectiveClass.produce(new ReflectiveClassBuildItem(true, false,
-                "org.apache.kudu.tserver.Tserver$ResourceMetricsPB",
-                "org.apache.kudu.tserver.Tserver$ResourceMetricsPB$Builder"));
-
-        reflectiveClass.produce(new ReflectiveClassBuildItem(false, false,
-                "org.apache.kudu.shaded.io.netty.channel.socket.nio.NioSocketChannel"));
-        reflectiveClass
-                .produce(new ReflectiveClassBuildItem(false, false,
-                        "org.apache.kudu.shaded.io.netty.channel.socket.nio.NioServerSocketChannel"));
-        reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, "java.util.LinkedHashMap"));
-        reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, "sun.nio.ch.SelectorImpl"));
-
-        NativeImageConfigBuildItem.Builder builder = NativeImageConfigBuildItem.builder()
-                //.addNativeImageSystemProperty("io.netty.noUnsafe", "true")
-                // Use small chunks to avoid a lot of wasted space. Default is 16mb * arenas (derived from core count)
-                // Since buffers are cached to threads, the malloc overhead is temporary anyway
-                .addNativeImageSystemProperty("io.netty.allocator.maxOrder", "1")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.ssl.JdkNpnApplicationProtocolNegotiator")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.ssl.ConscryptAlpnSslEngine")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslContext")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslClientContext")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.ssl.util.ThreadLocalInsecureRandom")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.buffer.ByteBufUtil$HexUtil")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.buffer.PooledByteBufAllocator")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.buffer.ByteBufAllocator")
-                .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.buffer.ByteBufUtil")
-                .addNativeImageSystemProperty("io.netty.leakDetection.level", "DISABLED");
-
-        try {
-            Class.forName("org.apache.kudu.shaded.io.netty.handler.codec.http.HttpObjectEncoder");
-            builder
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.codec.http.HttpObjectEncoder")
-                    .addRuntimeInitializedClass(
-                            "org.apache.kudu.shaded.io.netty.handler.codec.http.websocketx.extensions.compression.DeflateDecoder")
-                    .addRuntimeInitializedClass(
-                            "org.apache.kudu.shaded.io.netty.handler.codec.http.websocketx.WebSocket00FrameEncoder");
-        } catch (ClassNotFoundException e) {
-            //ignore
-            LOGGER.debug("Not registering Netty HTTP classes as they were not found");
-        }
-
-        try {
-            Class.forName("org.apache.kudu.shaded.io.netty.handler.codec.http2.Http2CodecUtil");
-            builder
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.codec.http2.Http2CodecUtil")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.codec.http2.Http2ClientUpgradeCodec")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.codec.http2.DefaultHttp2FrameWriter")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler");
-        } catch (ClassNotFoundException e) {
-            //ignore
-            LOGGER.debug("Not registering Netty HTTP2 classes as they were not found");
-        }
-
-        try {
-            Class.forName("org.apache.kudu.shaded.io.netty.channel.unix.UnixChannel");
-            builder.addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.unix.Errors")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.unix.FileDescriptor")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.unix.IovArray")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.unix.Limits");
-        } catch (ClassNotFoundException e) {
-            //ignore
-            LOGGER.debug("Not registering Netty native unix classes as they were not found");
-        }
-
-        try {
-            Class.forName("org.apache.kudu.shaded.io.netty.channel.epoll.EpollMode");
-            builder.addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.epoll.Epoll")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.epoll.EpollEventArray")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.epoll.EpollEventLoop")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.epoll.Native");
-        } catch (ClassNotFoundException e) {
-            //ignore
-            LOGGER.debug("Not registering Netty native epoll classes as they were not found");
-        }
-
-        try {
-            Class.forName("org.apache.kudu.shaded.io.netty.channel.kqueue.AcceptFilter");
-            builder.addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.kqueue.KQueue")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.kqueue.KQueueEventArray")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.kqueue.KQueueEventLoop")
-                    .addRuntimeInitializedClass("org.apache.kudu.shaded.io.netty.channel.kqueue.Native");
-        } catch (ClassNotFoundException e) {
-            //ignore
-            LOGGER.debug("Not registering Netty native kqueue classes as they were not found");
-        }
-
-        nativeImageConfig.produce(builder.build());
-    }
-
-    /*
-     * Adapted from https://github.com/quarkusio/quarkus/blob/master/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java
-     */
-    @BuildStep
-    public RuntimeReinitializedClassBuildItem nettyReinitScheduledFutureTask() {
-        return new RuntimeReinitializedClassBuildItem(
-                "org.apache.camel.quarkus.component.kudu.graal.Holder_io_netty_util_concurrent_ScheduledFutureTask");
-    }
-
-    /*
-     * Adapted from https://github.com/quarkusio/quarkus/blob/master/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java
-     */
-    @BuildStep
-    public List<UnsafeAccessedFieldBuildItem> nettyUnsafeAccessedFields() {
-        return Arrays.asList(
-                new UnsafeAccessedFieldBuildItem("sun.nio.ch.SelectorImpl", "selectedKeys"),
-                new UnsafeAccessedFieldBuildItem("sun.nio.ch.SelectorImpl", "publicSelectedKeys"),
-
-                new UnsafeAccessedFieldBuildItem(
-                        "org.apache.kudu.shaded.io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField",
-                        "producerIndex"),
-                new UnsafeAccessedFieldBuildItem(
-                        "org.apache.kudu.shaded.io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField",
-                        "producerLimit"),
-                new UnsafeAccessedFieldBuildItem(
-                        "org.apache.kudu.shaded.io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField",
-                        "consumerIndex"),
-
-                new UnsafeAccessedFieldBuildItem(
-                        "org.apache.kudu.shaded.io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields",
-                        "producerIndex"),
-                new UnsafeAccessedFieldBuildItem(
-                        "org.apache.kudu.shaded.io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields",
-                        "producerLimit"),
-                new UnsafeAccessedFieldBuildItem(
-                        "org.apache.kudu.shaded.io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields",
-                        "consumerIndex"));
-    }
-
-    /*
-     * Adapted from https://github.com/quarkusio/quarkus/blob/master/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java
-     */
-    @BuildStep
-    RuntimeInitializedClassBuildItem nettyRuntimeInitBcryptUtil() {
-        // this holds a direct allocated byte buffer that needs to be initialised at run time
-        return new RuntimeInitializedClassBuildItem(EmptyByteBufStub.class.getName());
-    }
-
 }
diff --git a/extensions/kudu/pom.xml b/extensions/kudu/pom.xml
index 889076f..7402309 100644
--- a/extensions/kudu/pom.xml
+++ b/extensions/kudu/pom.xml
@@ -31,6 +31,7 @@
     <packaging>pom</packaging>
 
     <modules>
+        <module>client</module>
         <module>deployment</module>
         <module>runtime</module>
     </modules>
diff --git a/extensions/kudu/runtime/pom.xml b/extensions/kudu/runtime/pom.xml
index 1a6e7af..c756046 100644
--- a/extensions/kudu/runtime/pom.xml
+++ b/extensions/kudu/runtime/pom.xml
@@ -49,11 +49,25 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-kudu-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core</artifactId>
         </dependency>
         <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-netty</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-kudu</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.kudu</groupId>
+                    <artifactId>kudu-client</artifactId><!-- replaced by camel-quarkus-kudu-client -->
+                </exclusion>
+            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.graalvm.nativeimage</groupId>
diff --git a/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/EmptyByteBufStub.java b/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/EmptyByteBufStub.java
deleted file mode 100644
index 0bd25f9..0000000
--- a/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/EmptyByteBufStub.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.quarkus.component.kudu.graal;
-
-import java.nio.ByteBuffer;
-
-import org.apache.kudu.shaded.io.netty.util.internal.PlatformDependent;
-
-/**
- * Adapted from
- * https://github.com/quarkusio/quarkus/blob/master/extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/EmptyByteBufStub.java
- */
-public final class EmptyByteBufStub {
-    private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocateDirect(0);
-    private static final long EMPTY_BYTE_BUFFER_ADDRESS;
-
-    static {
-        long emptyByteBufferAddress = 0;
-        try {
-            if (PlatformDependent.hasUnsafe()) {
-                emptyByteBufferAddress = PlatformDependent.directBufferAddress(EMPTY_BYTE_BUFFER);
-            }
-        } catch (Throwable t) {
-            // Ignore
-        }
-        EMPTY_BYTE_BUFFER_ADDRESS = emptyByteBufferAddress;
-    }
-
-    public static ByteBuffer emptyByteBuffer() {
-        return EMPTY_BYTE_BUFFER;
-    }
-
-    public static long emptyByteBufferAddress() {
-        return EMPTY_BYTE_BUFFER_ADDRESS;
-    }
-
-    private EmptyByteBufStub() {
-    }
-}
diff --git a/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/NettySubstitutions.java b/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/NettySubstitutions.java
deleted file mode 100644
index 6a498c6..0000000
--- a/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/NettySubstitutions.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.quarkus.component.kudu.graal;
-
-import java.nio.ByteBuffer;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.cert.X509Certificate;
-import java.util.Queue;
-import java.util.concurrent.LinkedBlockingDeque;
-
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.TrustManagerFactory;
-
-import com.oracle.svm.core.annotate.Alias;
-import com.oracle.svm.core.annotate.RecomputeFieldValue;
-import com.oracle.svm.core.annotate.Substitute;
-import com.oracle.svm.core.annotate.TargetClass;
-import com.oracle.svm.core.jdk.JDK8OrEarlier;
-import org.apache.kudu.shaded.io.netty.bootstrap.AbstractBootstrapConfig;
-import org.apache.kudu.shaded.io.netty.bootstrap.ChannelFactory;
-import org.apache.kudu.shaded.io.netty.buffer.ByteBufAllocator;
-import org.apache.kudu.shaded.io.netty.channel.Channel;
-import org.apache.kudu.shaded.io.netty.channel.ChannelFuture;
-import org.apache.kudu.shaded.io.netty.channel.DefaultChannelPromise;
-import org.apache.kudu.shaded.io.netty.handler.ssl.ApplicationProtocolConfig;
-import org.apache.kudu.shaded.io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
-import org.apache.kudu.shaded.io.netty.handler.ssl.CipherSuiteFilter;
-import org.apache.kudu.shaded.io.netty.handler.ssl.ClientAuth;
-import org.apache.kudu.shaded.io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator;
-import org.apache.kudu.shaded.io.netty.handler.ssl.JdkApplicationProtocolNegotiator;
-import org.apache.kudu.shaded.io.netty.handler.ssl.SslContext;
-import org.apache.kudu.shaded.io.netty.handler.ssl.SslProvider;
-import org.apache.kudu.shaded.io.netty.util.concurrent.GlobalEventExecutor;
-import org.apache.kudu.shaded.io.netty.util.internal.logging.InternalLoggerFactory;
-import org.apache.kudu.shaded.io.netty.util.internal.logging.JdkLoggerFactory;
-
-/**
- * This substitution avoid having loggers added to the build.
- * Adapted from
- * https://github.com/quarkusio/quarkus/blob/master/extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/graal/NettySubstitutions.java
- */
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.util.internal.logging.InternalLoggerFactory")
-final class Target_io_netty_util_internal_logging_InternalLoggerFactory {
-
-    @Substitute
-    private static InternalLoggerFactory newDefaultFactory(String name) {
-        return JdkLoggerFactory.INSTANCE;
-    }
-}
-
-// SSL
-// This whole section is mostly about removing static analysis references to openssl/tcnative
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.JdkSslServerContext")
-final class Target_io_netty_handler_ssl_JdkSslServerContext {
-
-    @Alias
-    Target_io_netty_handler_ssl_JdkSslServerContext(Provider provider,
-            X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
-            X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
-            KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
-            ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout,
-            ClientAuth clientAuth, String[] protocols, boolean startTls,
-            String keyStore)
-            throws SSLException {
-    }
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.JdkSslClientContext")
-final class Target_io_netty_handler_ssl_JdkSslClientContext {
-
-    @Alias
-    Target_io_netty_handler_ssl_JdkSslClientContext(Provider sslContextProvider, X509Certificate[] trustCertCollection,
-            TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key,
-            String keyPassword, KeyManagerFactory keyManagerFactory, Iterable<String> ciphers,
-            CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols,
-            long sessionCacheSize, long sessionTimeout, String keyStoreType)
-            throws SSLException {
-
-    }
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.SslHandler$SslEngineType")
-final class Target_io_netty_handler_ssl_SslHandler$SslEngineType {
-
-    @Alias
-    public static Target_io_netty_handler_ssl_SslHandler$SslEngineType JDK;
-
-    @Substitute
-    static Target_io_netty_handler_ssl_SslHandler$SslEngineType forEngine(SSLEngine engine) {
-        return JDK;
-    }
-}
-//
-//@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper", onlyWith = JDK11OrLater.class)
-//final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapper {
-//    @Substitute
-//    public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
-//            JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
-//        return (SSLEngine) (Object) new Target_io_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator, isServer);
-//    }
-//
-//}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper", onlyWith = JDK8OrEarlier.class)
-final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapperJava8 {
-    @Substitute
-    public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
-            JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
-        if (Target_io_netty_handler_ssl_JettyAlpnSslEngine.isAvailable()) {
-            return isServer
-                    ? (SSLEngine) (Object) Target_io_netty_handler_ssl_JettyAlpnSslEngine.newServerEngine(engine,
-                            applicationNegotiator)
-                    : (SSLEngine) (Object) Target_io_netty_handler_ssl_JettyAlpnSslEngine.newClientEngine(engine,
-                            applicationNegotiator);
-        }
-        throw new RuntimeException("Unable to wrap SSLEngine of type " + engine.getClass().getName());
-    }
-
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.JettyAlpnSslEngine", onlyWith = JDK8OrEarlier.class)
-final class Target_io_netty_handler_ssl_JettyAlpnSslEngine {
-    @Substitute
-    static boolean isAvailable() {
-        return false;
-    }
-
-    @Substitute
-    static Target_io_netty_handler_ssl_JettyAlpnSslEngine newClientEngine(SSLEngine engine,
-            JdkApplicationProtocolNegotiator applicationNegotiator) {
-        return null;
-    }
-
-    @Substitute
-    static Target_io_netty_handler_ssl_JettyAlpnSslEngine newServerEngine(SSLEngine engine,
-            JdkApplicationProtocolNegotiator applicationNegotiator) {
-        return null;
-    }
-}
-//
-//@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.JdkAlpnSslEngine", onlyWith = JDK11OrLater.class)
-//final class Target_io_netty_handler_ssl_JdkAlpnSslEngine {
-//    @Alias
-//    Target_io_netty_handler_ssl_JdkAlpnSslEngine(final SSLEngine engine,
-//            final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) {
-//
-//    }
-//}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.SslContext")
-final class Target_io_netty_handler_ssl_SslContext {
-
-    @Substitute
-    static SslContext newServerContextInternal(SslProvider provider,
-            Provider sslContextProvider,
-            X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
-            X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
-            long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls,
-            boolean enableOcsp, String keyStoreType)
-            throws SSLException {
-
-        if (enableOcsp) {
-            throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider);
-        }
-        return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslServerContext(sslContextProvider,
-                trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword,
-                keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout,
-                clientAuth, protocols, startTls, keyStoreType);
-    }
-
-    @Substitute
-    static SslContext newClientContextInternal(
-            SslProvider provider,
-            Provider sslContextProvider,
-            X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory,
-            X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
-            Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols,
-            long sessionCacheSize, long sessionTimeout, boolean enableOcsp, String keyStoreType) throws SSLException {
-        if (enableOcsp) {
-            throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider);
-        }
-        return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslClientContext(sslContextProvider,
-                trustCert, trustManagerFactory, keyCertChain, key, keyPassword,
-                keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize,
-                sessionTimeout, keyStoreType);
-    }
-
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.JdkDefaultApplicationProtocolNegotiator")
-final class Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator {
-
-    @Alias
-    public static Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator INSTANCE;
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.ssl.JdkSslContext")
-final class Target_io_netty_handler_ssl_JdkSslContext {
-
-    @Substitute
-    static JdkApplicationProtocolNegotiator toNegotiator(ApplicationProtocolConfig config, boolean isServer) {
-        if (config == null) {
-            return (JdkApplicationProtocolNegotiator) (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE;
-        }
-
-        switch (config.protocol()) {
-        case NONE:
-            return (JdkApplicationProtocolNegotiator) (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE;
-        case ALPN:
-            if (isServer) {
-                // GRAAL RC9 bug: https://github.com/oracle/graal/issues/813
-                //                switch(config.selectorFailureBehavior()) {
-                //                case FATAL_ALERT:
-                //                    return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols());
-                //                case NO_ADVERTISE:
-                //                    return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols());
-                //                default:
-                //                    throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ")
-                //                    .append(config.selectorFailureBehavior()).append(" failure behavior").toString());
-                //                }
-                SelectorFailureBehavior behavior = config.selectorFailureBehavior();
-                if (behavior == SelectorFailureBehavior.FATAL_ALERT)
-                    return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols());
-                else if (behavior == SelectorFailureBehavior.NO_ADVERTISE)
-                    return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols());
-                else {
-                    throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ")
-                            .append(config.selectorFailureBehavior()).append(" failure behavior").toString());
-                }
-            } else {
-                switch (config.selectedListenerFailureBehavior()) {
-                case ACCEPT:
-                    return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols());
-                case FATAL_ALERT:
-                    return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols());
-                default:
-                    throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ")
-                            .append(config.selectedListenerFailureBehavior()).append(" failure behavior").toString());
-                }
-            }
-        default:
-            throw new UnsupportedOperationException(
-                    new StringBuilder("JDK provider does not support ").append(config.protocol()).append(" protocol")
-                            .toString());
-        }
-    }
-
-}
-
-/*
- * This one only prints exceptions otherwise we get a useless bogus
- * exception message: https://github.com/eclipse-vertx/vert.x/issues/1657
- */
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.bootstrap.AbstractBootstrap")
-final class Target_io_netty_bootstrap_AbstractBootstrap {
-
-    @Alias
-    private ChannelFactory channelFactory;
-
-    @Alias
-    void init(Channel channel) throws Exception {
-    }
-
-    @Alias
-    public AbstractBootstrapConfig config() {
-        return null;
-    }
-
-    @Substitute
-    final ChannelFuture initAndRegister() {
-        Channel channel = null;
-        try {
-            channel = channelFactory.newChannel();
-            init(channel);
-        } catch (Throwable t) {
-            // THE FIX IS HERE:
-            t.printStackTrace();
-            if (channel != null) {
-                // channel can be null if newChannel crashed (eg SocketException("too many open files"))
-                channel.unsafe().closeForcibly();
-            }
-            // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
-            return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
-        }
-
-        ChannelFuture regFuture = config().group().register(channel);
-        if (regFuture.cause() != null) {
-            if (channel.isRegistered()) {
-                channel.close();
-            } else {
-                channel.unsafe().closeForcibly();
-            }
-        }
-
-        // If we are here and the promise is not failed, it's one of the following cases:
-        // 1) If we attempted registration from the event loop, the registration has been completed at this point.
-        //    i.e. It's safe to attempt bind() or connect() now because the channel has been registered.
-        // 2) If we attempted registration from the other thread, the registration request has been successfully
-        //    added to the event loop's task queue for later execution.
-        //    i.e. It's safe to attempt bind() or connect() now:
-        //         because bind() or connect() will be executed *after* the scheduled registration task is executed
-        //         because register(), bind(), and connect() are all bound to the same thread.
-
-        return regFuture;
-
-    }
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.channel.nio.NioEventLoop")
-final class Target_io_netty_channel_nio_NioEventLoop {
-
-    @Substitute
-    private static Queue<Runnable> newTaskQueue0(int maxPendingTasks) {
-        return new LinkedBlockingDeque<>();
-    }
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.buffer.AbstractReferenceCountedByteBuf")
-final class Target_io_netty_buffer_AbstractReferenceCountedByteBuf {
-
-    @Alias
-    @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FieldOffset, name = "refCnt")
-    private static long REFCNT_FIELD_OFFSET;
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.util.AbstractReferenceCounted")
-final class Target_io_netty_util_AbstractReferenceCounted {
-
-    @Alias
-    @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FieldOffset, name = "refCnt")
-    private static long REFCNT_FIELD_OFFSET;
-}
-
-// This class is runtime-initialized by NettyProcessor
-final class Holder_io_netty_util_concurrent_ScheduledFutureTask {
-    static final long START_TIME = System.nanoTime();
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.util.concurrent.ScheduledFutureTask")
-final class Target_io_netty_util_concurrent_ScheduledFutureTask {
-
-    // The START_TIME field is kept but not used.
-    // All the accesses to it have been replaced with Holder_io_netty_util_concurrent_ScheduledFutureTask
-
-    @Substitute
-    static long initialNanoTime() {
-        return Holder_io_netty_util_concurrent_ScheduledFutureTask.START_TIME;
-    }
-
-    @Substitute
-    static long nanoTime() {
-        return System.nanoTime() - Holder_io_netty_util_concurrent_ScheduledFutureTask.START_TIME;
-    }
-
-    @Alias
-    public long deadlineNanos() {
-        return 0;
-    }
-
-    @Substitute
-    public long delayNanos(long currentTimeNanos) {
-        return Math.max(0,
-                deadlineNanos() - (currentTimeNanos - Holder_io_netty_util_concurrent_ScheduledFutureTask.START_TIME));
-    }
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.channel.ChannelHandlerMask")
-final class Target_io_netty_channel_ChannelHandlerMask {
-
-    // Netty tries to self-optimized itself, but it requires lots of reflection. We disable this behavior and avoid
-    // misleading DEBUG messages in the log.
-    @Substitute
-    private static boolean isSkippable(final Class<?> handlerType, final String methodName, final Class... paramTypes) {
-        return false;
-    }
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.util.internal.NativeLibraryLoader")
-final class Target_io_netty_util_internal_NativeLibraryLoader {
-
-    // This method can trick GraalVM into thinking that Classloader#defineClass is getting called
-    @Substitute
-    static Class<?> tryToLoadClass(final ClassLoader loader, final Class<?> helper)
-            throws ClassNotFoundException {
-        return Class.forName(helper.getName(), false, loader);
-    }
-
-}
-
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.buffer.EmptyByteBuf")
-final class Target_io_netty_buffer_EmptyByteBuf {
-
-    @Alias
-    @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset)
-    private static ByteBuffer EMPTY_BYTE_BUFFER;
-
-    @Alias
-    @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset)
-    private static long EMPTY_BYTE_BUFFER_ADDRESS;
-
-    @Substitute
-    public ByteBuffer nioBuffer() {
-        return EmptyByteBufStub.emptyByteBuffer();
-    }
-
-    @Substitute
-    public ByteBuffer[] nioBuffers() {
-        return new ByteBuffer[] { EmptyByteBufStub.emptyByteBuffer() };
-    }
-
-    @Substitute
-    public ByteBuffer internalNioBuffer(int index, int length) {
-        return EmptyByteBufStub.emptyByteBuffer();
-    }
-
-    @Substitute
-    public boolean hasMemoryAddress() {
-        return EmptyByteBufStub.emptyByteBufferAddress() != 0;
-    }
-
-    @Substitute
-    public long memoryAddress() {
-        if (hasMemoryAddress()) {
-            return EmptyByteBufStub.emptyByteBufferAddress();
-        } else {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-}
-
-class NettySubstitutions {
-
-}
diff --git a/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/ZLibSubstitutions.java b/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/ZLibSubstitutions.java
deleted file mode 100644
index 9e80749..0000000
--- a/extensions/kudu/runtime/src/main/java/org/apache/camel/quarkus/component/kudu/graal/ZLibSubstitutions.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.quarkus.component.kudu.graal;
-
-import com.oracle.svm.core.annotate.Substitute;
-import com.oracle.svm.core.annotate.TargetClass;
-import org.apache.kudu.shaded.io.netty.handler.codec.compression.JdkZlibDecoder;
-import org.apache.kudu.shaded.io.netty.handler.codec.compression.JdkZlibEncoder;
-import org.apache.kudu.shaded.io.netty.handler.codec.compression.ZlibDecoder;
-import org.apache.kudu.shaded.io.netty.handler.codec.compression.ZlibEncoder;
-import org.apache.kudu.shaded.io.netty.handler.codec.compression.ZlibWrapper;
-
-/**
- * This substitution avoid having jcraft zlib added to the build
- * Adapted from
- * https://github.com/quarkusio/quarkus/blob/master/extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/graal/ZLibSubstitutions.java
- */
-@TargetClass(className = "org.apache.kudu.shaded.io.netty.handler.codec.compression.ZlibCodecFactory")
-final class Target_io_netty_handler_codec_compression_ZlibCodecFactory {
-
-    @Substitute
-    public static ZlibEncoder newZlibEncoder(int compressionLevel) {
-        return new JdkZlibEncoder(compressionLevel);
-    }
-
-    @Substitute
-    public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper) {
-        return new JdkZlibEncoder(wrapper);
-    }
-
-    @Substitute
-    public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel) {
-        return new JdkZlibEncoder(wrapper, compressionLevel);
-    }
-
-    @Substitute
-    public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) {
-        return new JdkZlibEncoder(wrapper, compressionLevel);
-    }
-
-    @Substitute
-    public static ZlibEncoder newZlibEncoder(byte[] dictionary) {
-        return new JdkZlibEncoder(dictionary);
-    }
-
-    @Substitute
-    public static ZlibEncoder newZlibEncoder(int compressionLevel, byte[] dictionary) {
-        return new JdkZlibEncoder(compressionLevel, dictionary);
-    }
-
-    @Substitute
-    public static ZlibEncoder newZlibEncoder(int compressionLevel, int windowBits, int memLevel, byte[] dictionary) {
-        return new JdkZlibEncoder(compressionLevel, dictionary);
-    }
-
-    @Substitute
-    public static ZlibDecoder newZlibDecoder() {
-        return new JdkZlibDecoder();
-    }
-
-    @Substitute
-    public static ZlibDecoder newZlibDecoder(ZlibWrapper wrapper) {
-        return new JdkZlibDecoder(wrapper);
-    }
-
-    @Substitute
-    public static ZlibDecoder newZlibDecoder(byte[] dictionary) {
-        return new JdkZlibDecoder(dictionary);
-    }
-}
-
-class ZLibSubstitutions {
-
-}
diff --git a/pom.xml b/pom.xml
index 1134985..6d40236 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,6 +78,7 @@
         <jetty.version>9.4.18.v20190429</jetty.version>
         <jnr-ffi.version>2.1.2</jnr-ffi.version><!-- Mess in web3j transitive deps -->
         <kafka.version>2.5.0</kafka.version>
+        <kudu.version>1.12.0</kudu.version><!-- keep in sync with Camel -->
         <kubernetes-client.version>4.10.3</kubernetes-client.version>
         <kotlin.version>1.3.72</kotlin.version>
         <netty3.version>3.10.6.Final</netty3.version><!-- Spark -->
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index ab3e1e7..67993fa 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -3762,6 +3762,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-kudu-client</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
                 <artifactId>camel-quarkus-kudu-deployment</artifactId>
                 <version>${camel-quarkus.version}</version>
             </dependency>
@@ -5527,6 +5532,11 @@
                 <version>${kafka.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.apache.kudu</groupId>
+                <artifactId>kudu-client</artifactId>
+                <version>${kudu.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.apache.xmlgraphics</groupId>
                 <artifactId>xmlgraphics-commons</artifactId>
                 <version>${xmlgraphics-commons.version}</version>