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;
