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

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

commit e9e9805071dc48e3402b87fb312a4fe9d7fb093e
Author: James Netherton <[email protected]>
AuthorDate: Fri Jul 3 12:10:11 2026 +0100

    Fix native build failures caused by httpclient5 5.6.x upgrade
    
    httpclient5 5.6.x switched Brotli from org.brotli:dec to brotli4j and
    added CommonsCompressCodecFactory which pulls in optional tukaani XZ.
    Update the Brotli stub and supplier for brotli4j, and add GraalVM
    substitutions for CommonsCompressCodecFactory to cut the reachability
    chain to the missing XZ dependency.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../deployment/HttpClient5Processor.java           |  4 +-
 .../graal/BrotliAbsentBooleanSupplier.java         |  2 +-
 .../httpclient5/graal/BrotliSubstitutions.java     |  4 +-
 .../graal/CommonsCompressSubstitutions.java        | 58 ++++++++++++++++++++++
 ...nSupplier.java => XzAbsentBooleanSupplier.java} | 10 +++-
 5 files changed, 71 insertions(+), 7 deletions(-)

diff --git 
a/extensions-support/httpclient5/deployment/src/main/java/org/apache/camel/quarkus/support/httpclient5/deployment/HttpClient5Processor.java
 
b/extensions-support/httpclient5/deployment/src/main/java/org/apache/camel/quarkus/support/httpclient5/deployment/HttpClient5Processor.java
index 5586c9fd89..84b9c4dac3 100644
--- 
a/extensions-support/httpclient5/deployment/src/main/java/org/apache/camel/quarkus/support/httpclient5/deployment/HttpClient5Processor.java
+++ 
b/extensions-support/httpclient5/deployment/src/main/java/org/apache/camel/quarkus/support/httpclient5/deployment/HttpClient5Processor.java
@@ -33,7 +33,7 @@ import io.quarkus.gizmo.MethodDescriptor;
 import 
org.apache.camel.quarkus.support.httpclient5.graal.BrotliAbsentBooleanSupplier;
 
 class HttpClient5Processor {
-    private static final String BROTLI_INPUT_STREAM_CLASS_NAME = 
"org.brotli.dec.BrotliInputStream";
+    private static final String BROTLI_INPUT_STREAM_CLASS_NAME = 
"com.aayushatharva.brotli4j.decoder.BrotliInputStream";
     private static final String NTLM_ENGINE_IMPL = 
"org.apache.hc.client5.http.impl.auth.NTLMEngineImpl";
 
     @BuildStep
@@ -90,7 +90,7 @@ class HttpClient5Processor {
                 readMethod.setModifiers(Modifier.PUBLIC);
                 readMethod.addException(IOException.class);
                 readMethod.throwException(UnsupportedOperationException.class,
-                        "Cannot read from BrotliInputStream. Add 
org.brotli:dec to the application classpath");
+                        "Cannot read from BrotliInputStream. Add 
com.aayushatharva.brotli4j:brotli4j to the application classpath");
             }
         }
     }
diff --git 
a/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliAbsentBooleanSupplier.java
 
b/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliAbsentBooleanSupplier.java
index ad39e64d11..5c867c3b75 100644
--- 
a/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliAbsentBooleanSupplier.java
+++ 
b/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliAbsentBooleanSupplier.java
@@ -22,7 +22,7 @@ public class BrotliAbsentBooleanSupplier implements 
BooleanSupplier {
     @Override
     public boolean getAsBoolean() {
         try {
-            
Thread.currentThread().getContextClassLoader().loadClass("org.brotli.dec.Decoder");
+            
Thread.currentThread().getContextClassLoader().loadClass("com.aayushatharva.brotli4j.Brotli4jLoader");
             return false;
         } catch (ClassNotFoundException e) {
             return true;
diff --git 
a/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliSubstitutions.java
 
b/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliSubstitutions.java
index bc2ffeba2d..c18eb08dd8 100644
--- 
a/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliSubstitutions.java
+++ 
b/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliSubstitutions.java
@@ -25,7 +25,7 @@ import 
org.apache.hc.client5.http.entity.BrotliDecompressingEntity;
 import org.apache.hc.client5.http.entity.BrotliInputStreamFactory;
 
 /**
- * Remove references to optional brotli:dec dependency.
+ * Remove references to optional brotli4j dependency.
  */
 final class BrotliSubstitutions {
 }
@@ -35,7 +35,7 @@ final class SubstituteBrotliInputStreamFactory {
     @Substitute
     public InputStream create(InputStream inputStream) throws IOException {
         throw new UnsupportedOperationException(
-                "Cannot create BrotliInputStream. Add org.brotli:dec to the 
application classpath.");
+                "Cannot create BrotliInputStream. Add 
com.aayushatharva.brotli4j:brotli4j to the application classpath.");
     }
 }
 
diff --git 
a/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/CommonsCompressSubstitutions.java
 
b/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/CommonsCompressSubstitutions.java
new file mode 100644
index 0000000000..b7bcb5a814
--- /dev/null
+++ 
b/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/CommonsCompressSubstitutions.java
@@ -0,0 +1,58 @@
+/*
+ * 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.support.httpclient5.graal;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+import org.apache.hc.client5.http.entity.compress.ContentCoding;
+import org.apache.hc.core5.io.IOFunction;
+
+/**
+ * Prevent GraalVM from following the reference chain from 
CommonsCompressCodecFactory
+ * to CompressorStreamFactory to XZCompressorInputStream to the optional 
org.tukaani:xz dependency.
+ */
+final class CommonsCompressSubstitutions {
+}
+
+@TargetClass(className = 
"org.apache.hc.client5.http.entity.compress.CommonsCompressRuntime", onlyWith = 
XzAbsentBooleanSupplier.class)
+final class SubstituteCommonsCompressRuntime {
+    @Substitute
+    static boolean available() {
+        return false;
+    }
+}
+
+@TargetClass(className = 
"org.apache.hc.client5.http.entity.compress.CommonsCompressCodecFactory", 
onlyWith = XzAbsentBooleanSupplier.class)
+final class SubstituteCommonsCompressCodecFactory {
+    @Substitute
+    static IOFunction<InputStream, InputStream> decoder(String name) {
+        return null;
+    }
+
+    @Substitute
+    static IOFunction<OutputStream, OutputStream> encoder(String name) {
+        return null;
+    }
+
+    @Substitute
+    static boolean runtimeAvailable(ContentCoding contentCoding) {
+        return false;
+    }
+}
diff --git 
a/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliAbsentBooleanSupplier.java
 
b/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/XzAbsentBooleanSupplier.java
similarity index 73%
copy from 
extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliAbsentBooleanSupplier.java
copy to 
extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/XzAbsentBooleanSupplier.java
index ad39e64d11..fa46325bfa 100644
--- 
a/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/BrotliAbsentBooleanSupplier.java
+++ 
b/extensions-support/httpclient5/runtime/src/main/java/org/apache/camel/quarkus/support/httpclient5/graal/XzAbsentBooleanSupplier.java
@@ -18,11 +18,17 @@ package org.apache.camel.quarkus.support.httpclient5.graal;
 
 import java.util.function.BooleanSupplier;
 
-public class BrotliAbsentBooleanSupplier implements BooleanSupplier {
+public class XzAbsentBooleanSupplier implements BooleanSupplier {
     @Override
     public boolean getAsBoolean() {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
         try {
-            
Thread.currentThread().getContextClassLoader().loadClass("org.brotli.dec.Decoder");
+            
cl.loadClass("org.apache.commons.compress.compressors.CompressorStreamFactory");
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+        try {
+            cl.loadClass("org.tukaani.xz.XZInputStream");
             return false;
         } catch (ClassNotFoundException e) {
             return true;

Reply via email to