This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 57359ca3095b CAMEL-23939: Fix Kamelet dependencies ignored in Camel CLI
57359ca3095b is described below
commit 57359ca3095b1f6dbc3c1c5410a9b81fc085ba3b
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jul 9 05:30:06 2026 +0200
CAMEL-23939: Fix Kamelet dependencies ignored in Camel CLI
DelegatingSchemaResolver has hard imports to AvroSchemaResolver,
ProtobufSchemaResolver, and JsonSchemaResolver from provided-scope
dependencies. When running via Camel CLI, these are downloaded into
a child classloader but DelegatingSchemaResolver is on the parent
classpath and cannot see them, causing NoClassDefFoundError.
Add a try/catch fallback: direct instantiation is tried first (works
on flat classpaths like Spring Boot), and on NoClassDefFoundError the
resolver is loaded reflectively via CamelContext's ClassResolver which
can see dynamically downloaded JARs.
Closes #24544
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../format/schema/DelegatingSchemaResolver.java | 70 ++++++++++++++++++++--
1 file changed, 64 insertions(+), 6 deletions(-)
diff --git
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/utils/format/schema/DelegatingSchemaResolver.java
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/utils/format/schema/DelegatingSchemaResolver.java
index aa317448fbbe..b7794305d5f5 100644
---
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/utils/format/schema/DelegatingSchemaResolver.java
+++
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/utils/format/schema/DelegatingSchemaResolver.java
@@ -17,6 +17,8 @@
package org.apache.camel.component.kamelet.utils.format.schema;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.component.jackson.avro.transform.AvroSchemaResolver;
@@ -31,13 +33,30 @@ import org.apache.camel.util.ObjectHelper;
* determine the schema resolver (Avro or Json). Delegates to schema resolver
and sets proper content class and schema
* properties on the delegate.
*/
-public class DelegatingSchemaResolver implements Processor {
+public class DelegatingSchemaResolver implements Processor, CamelContextAware {
+
+ private static final String AVRO_SCHEMA_RESOLVER =
"org.apache.camel.component.jackson.avro.transform.AvroSchemaResolver";
+ private static final String PROTOBUF_SCHEMA_RESOLVER
+ =
"org.apache.camel.component.jackson.protobuf.transform.ProtobufSchemaResolver";
+ private static final String JSON_SCHEMA_RESOLVER =
"org.apache.camel.component.jackson.transform.JsonSchemaResolver";
+
+ private CamelContext camelContext;
private String mimeType;
private String targetMimeType;
private String schema;
private String contentClass;
+ @Override
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
@Override
public void process(Exchange exchange) throws Exception {
if (ObjectHelper.isEmpty(mimeType)) {
@@ -65,19 +84,41 @@ public class DelegatingSchemaResolver implements Processor {
case PROTOBUF:
case PROTOBUF_BINARY:
case PROTOBUF_STRUCT:
+ return createSchemaResolver(PROTOBUF_SCHEMA_RESOLVER);
+ case AVRO:
+ case AVRO_BINARY:
+ case AVRO_STRUCT:
+ return createSchemaResolver(AVRO_SCHEMA_RESOLVER);
+ case JSON:
+ case STRUCT:
+ return createSchemaResolver(JSON_SCHEMA_RESOLVER);
+ default:
+ return null;
+ }
+ }
+
+ private Processor createSchemaResolver(String className) {
+ try {
+ return doCreateSchemaResolver(className);
+ } catch (NoClassDefFoundError e) {
+ // fallback to dynamic class resolution (e.g. Camel CLI with
downloaded dependencies)
+ return doCreateSchemaResolverReflection(className);
+ }
+ }
+
+ private Processor doCreateSchemaResolver(String className) {
+ switch (className) {
+ case PROTOBUF_SCHEMA_RESOLVER:
ProtobufSchemaResolver protobufSchemaResolver = new
ProtobufSchemaResolver();
protobufSchemaResolver.setSchema(this.schema);
protobufSchemaResolver.setContentClass(this.contentClass);
return protobufSchemaResolver;
- case AVRO:
- case AVRO_BINARY:
- case AVRO_STRUCT:
+ case AVRO_SCHEMA_RESOLVER:
AvroSchemaResolver avroSchemaResolver = new
AvroSchemaResolver();
avroSchemaResolver.setSchema(this.schema);
avroSchemaResolver.setContentClass(this.contentClass);
return avroSchemaResolver;
- case JSON:
- case STRUCT:
+ case JSON_SCHEMA_RESOLVER:
JsonSchemaResolver jsonSchemaResolver = new
JsonSchemaResolver();
jsonSchemaResolver.setSchema(this.schema);
jsonSchemaResolver.setContentClass(this.contentClass);
@@ -87,6 +128,23 @@ public class DelegatingSchemaResolver implements Processor {
}
}
+ private Processor doCreateSchemaResolverReflection(String className) {
+ try {
+ Class<?> clazz;
+ if (camelContext != null) {
+ clazz =
camelContext.getClassResolver().resolveMandatoryClass(className);
+ } else {
+ clazz =
Thread.currentThread().getContextClassLoader().loadClass(className);
+ }
+ Object instance = clazz.getDeclaredConstructor().newInstance();
+ clazz.getMethod("setSchema", String.class).invoke(instance,
this.schema);
+ clazz.getMethod("setContentClass", String.class).invoke(instance,
this.contentClass);
+ return (Processor) instance;
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot create schema resolver: " +
className, e);
+ }
+ }
+
public String getMimeType() {
return mimeType;
}