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


The following commit(s) were added to refs/heads/main by this push:
     new d199abd1d9 Reduce OpenAI extension native reflection registrations
d199abd1d9 is described below

commit d199abd1d9c970ea7520235ad8ce3a365c0ea443
Author: James Netherton <[email protected]>
AuthorDate: Wed Oct 14 08:04:29 2026 +0100

    Reduce OpenAI extension native reflection registrations
    
    Only index and register the OpenAI Java SDK model classes required by the 
Camel OpenAI component.
    
    Co-authored-by: Claude Opus 5.5 <[email protected]>
---
 .../openai/deployment/OpenaiProcessor.java         | 50 +++++++++++++++++++++-
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git 
a/extensions/openai/deployment/src/main/java/org/apache/camel/quarkus/component/openai/deployment/OpenaiProcessor.java
 
b/extensions/openai/deployment/src/main/java/org/apache/camel/quarkus/component/openai/deployment/OpenaiProcessor.java
index 5667a8554d..62c36d0b17 100644
--- 
a/extensions/openai/deployment/src/main/java/org/apache/camel/quarkus/component/openai/deployment/OpenaiProcessor.java
+++ 
b/extensions/openai/deployment/src/main/java/org/apache/camel/quarkus/component/openai/deployment/OpenaiProcessor.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.quarkus.component.openai.deployment;
 
+import java.util.HashSet;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -28,6 +29,7 @@ import io.quarkus.deployment.Capabilities;
 import io.quarkus.deployment.Capability;
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.AdditionalIndexedClassesBuildItem;
 import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
 import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
@@ -36,15 +38,26 @@ import 
io.quarkus.deployment.builditem.nativeimage.NativeImageResourcePatternsBu
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
 import 
io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
+import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
 import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
 import io.quarkus.jackson.deployment.IgnoreJsonDeserializeClassBuildItem;
 import io.quarkus.maven.dependency.ArtifactKey;
+import io.quarkus.paths.PathFilter;
+import org.apache.camel.util.StringHelper;
 import org.jboss.jandex.ClassInfo;
 import org.jboss.jandex.DotName;
 import org.jboss.jandex.Type;
 
 class OpenaiProcessor {
     private static final String FEATURE = "camel-openai";
+    private static final String OPENAI_MODELS_PACKAGE = "com.openai.models.";
+    // The model packages backing the operations of the Camel OpenAI 
component, plus the packages they depend on
+    private static final Set<String> OPENAI_MODELS_SUB_PACKAGES = Set.of(
+            "audio",
+            "chat",
+            "completions",
+            "embeddings",
+            "responses");
 
     @BuildStep
     FeatureBuildItem feature() {
@@ -53,10 +66,33 @@ class OpenaiProcessor {
 
     @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
     void indexDependencies(BuildProducer<IndexDependencyBuildItem> 
indexDependency) {
-        indexDependency.produce(new IndexDependencyBuildItem("com.openai", 
"openai-java-core"));
         indexDependency.produce(new 
IndexDependencyBuildItem("io.modelcontextprotocol.sdk", "mcp-core"));
     }
 
+    @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
+    void indexOpenAIClasses(
+            CurateOutcomeBuildItem curateOutcome,
+            BuildProducer<AdditionalIndexedClassesBuildItem> 
additionalIndexedClasses) {
+        // openai-java-core is not indexed as a whole. Around 80% of its model 
classes (beta, admin, realtime, evals etc.)
+        // are not used by the Camel OpenAI component. If they were indexed, 
quarkus-jackson would register them for
+        // reflection, which makes the native build considerably slower and 
the native executable larger
+        Set<String> openAIClassNames = new HashSet<>();
+        PathFilter pathFilter = 
PathFilter.forIncludes(Set.of("com/openai/**/*.class"));
+        curateOutcome.getApplicationModel()
+                .getRuntimeDependencies()
+                .stream()
+                .filter(dependency -> 
dependency.getGroupId().equals("com.openai")
+                        && 
dependency.getArtifactId().equals("openai-java-core"))
+                .forEach(dependency -> 
dependency.getContentTree(pathFilter).walk(visit -> {
+                    String className = 
StringHelper.before(visit.getResourceName(), ".class").replace('/', '.');
+                    if (isRequiredClass(className)) {
+                        openAIClassNames.add(className);
+                    }
+                }));
+
+        additionalIndexedClasses.produce(new 
AdditionalIndexedClassesBuildItem(openAIClassNames.toArray(new String[0])));
+    }
+
     @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
     void 
registerMcpSdkServiceProviders(BuildProducer<ServiceProviderBuildItem> 
serviceProvider) {
         // the MCP client (mcpServer.* endpoint options) resolves its JSON 
mapper and schema
@@ -126,7 +162,7 @@ class OpenaiProcessor {
                     .stream()
                     .map(ClassInfo::name)
                     .map(DotName::toString)
-                    .filter(className -> 
className.startsWith("com.openai.models"))
+                    .filter(className -> 
className.startsWith(OPENAI_MODELS_PACKAGE))
                     .collect(Collectors.toSet());
 
             
reflectiveClass.produce(ReflectiveClassBuildItem.builder(openAIModelClassNames.toArray(new
 String[0]))
@@ -142,6 +178,16 @@ class OpenaiProcessor {
         }
     }
 
+    private static boolean isRequiredClass(String className) {
+        if (!className.startsWith(OPENAI_MODELS_PACKAGE)) {
+            return true;
+        }
+        String relativeName = 
className.substring(OPENAI_MODELS_PACKAGE.length());
+        int idx = relativeName.indexOf('.');
+        // Classes that are directly within com.openai.models are shared 
across the sub packages
+        return idx == -1 || 
OPENAI_MODELS_SUB_PACKAGES.contains(relativeName.substring(0, idx));
+    }
+
     @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
     RemovedResourceBuildItem excludeNativeImageDirectives() {
         // Remove all native-image directives from openai-java-core as it's 
mostly redundant & inaccurate for Quarkus

Reply via email to