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 8b5e11da18e4 camel-groovy - Using groovyJson can work with simple 
jsonpath for basic jsonpath expressions. Add support for path from json array 
object as root. (#21940)
8b5e11da18e4 is described below

commit 8b5e11da18e4e8cb1ef3b73158b9802744e9c1a0
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Mar 11 18:18:11 2026 +0100

    camel-groovy - Using groovyJson can work with simple jsonpath for basic 
jsonpath expressions. Add support for path from json array object as root. 
(#21940)
---
 .../groovy/json/GroovyJsonBulkConverterLoader.java | 126 +++++++++++++++++++++
 .../services/org/apache/camel/TypeConverterLoader  |   2 +
 .../camel/groovy/json/GroovyJsonConverter.java     |  68 +++++++++++
 .../groovy/json/GroovySimpleJSonArrayOnlyTest.java |  61 ++++++++++
 .../groovy/json/GroovySimpleJSonArrayTest.java     |  62 ++++++++++
 .../camel/groovy/json/GroovySimpleJSonTest.java    |  77 +++++++++++++
 .../language/simple/SimpleExpressionBuilder.java   |  11 +-
 .../org/apache/camel/util/json/JsonObject.java     |  40 +++++--
 .../apache/camel/util/json/JsonObjectPathTest.java |  29 +++++
 9 files changed, 465 insertions(+), 11 deletions(-)

diff --git 
a/components/camel-groovy/src/generated/java/org/apache/camel/groovy/json/GroovyJsonBulkConverterLoader.java
 
b/components/camel-groovy/src/generated/java/org/apache/camel/groovy/json/GroovyJsonBulkConverterLoader.java
new file mode 100644
index 000000000000..12575f79009c
--- /dev/null
+++ 
b/components/camel-groovy/src/generated/java/org/apache/camel/groovy/json/GroovyJsonBulkConverterLoader.java
@@ -0,0 +1,126 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.groovy.json;
+
+import javax.annotation.processing.Generated;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.DeferredContextBinding;
+import org.apache.camel.Exchange;
+import org.apache.camel.Ordered;
+import org.apache.camel.TypeConversionException;
+import org.apache.camel.TypeConverterLoaderException;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.spi.TypeConvertible;
+import org.apache.camel.spi.BulkTypeConverters;
+import org.apache.camel.spi.TypeConverterLoader;
+import org.apache.camel.spi.TypeConverterRegistry;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.TypeConverterLoaderGeneratorMojo")
+@SuppressWarnings("unchecked")
+@DeferredContextBinding
+public final class GroovyJsonBulkConverterLoader implements 
TypeConverterLoader, BulkTypeConverters, CamelContextAware {
+
+    private CamelContext camelContext;
+
+    public GroovyJsonBulkConverterLoader() {
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public int size() {
+        return 6;
+    }
+
+    @Override
+    public void load(TypeConverterRegistry registry) throws 
TypeConverterLoaderException {
+        registry.addBulkTypeConverters(this);
+        doRegistration(registry);
+    }
+
+    @Override
+    public <T> T convertTo(Class<?> from, Class<T> to, Exchange exchange, 
Object value) throws TypeConversionException {
+        try {
+            Object obj = doConvertTo(from, to, exchange, value);
+            return (T) obj;
+        } catch (TypeConversionException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new TypeConversionException(value, to, e);
+        }
+    }
+
+    private Object doConvertTo(Class<?> from, Class<?> to, Exchange exchange, 
Object value) throws Exception {
+        if (to == org.apache.camel.util.json.JsonArray.class) {
+            if (value instanceof java.util.List) {
+                return 
org.apache.camel.groovy.json.GroovyJsonConverter.convertToJsonArray((java.util.List)
 value, exchange);
+            }
+        } else if (to == org.apache.camel.util.json.JsonObject.class) {
+            if (value instanceof groovy.util.Node) {
+                return 
org.apache.camel.groovy.json.GroovyJsonConverter.convertToJsonObject((groovy.util.Node)
 value, exchange);
+            }
+            if (value instanceof org.apache.groovy.json.internal.LazyMap) {
+                return 
org.apache.camel.groovy.json.GroovyJsonConverter.convertToJsonObject((org.apache.groovy.json.internal.LazyMap)
 value, exchange);
+            }
+        } else if (to == org.apache.camel.util.json.Jsonable.class) {
+            if (value instanceof groovy.util.Node) {
+                return 
org.apache.camel.groovy.json.GroovyJsonConverter.convertToJson((groovy.util.Node)
 value, exchange);
+            }
+            if (value instanceof org.apache.groovy.json.internal.LazyMap) {
+                return 
org.apache.camel.groovy.json.GroovyJsonConverter.convertToJson((org.apache.groovy.json.internal.LazyMap)
 value, exchange);
+            }
+            if (value instanceof java.util.List) {
+                return 
org.apache.camel.groovy.json.GroovyJsonConverter.convertToJson((java.util.List) 
value, exchange);
+            }
+        }
+        return null;
+    }
+
+    private void doRegistration(TypeConverterRegistry registry) {
+        registry.addConverter(new TypeConvertible<>(java.util.List.class, 
org.apache.camel.util.json.JsonArray.class), this);
+        registry.addConverter(new TypeConvertible<>(groovy.util.Node.class, 
org.apache.camel.util.json.JsonObject.class), this);
+        registry.addConverter(new 
TypeConvertible<>(org.apache.groovy.json.internal.LazyMap.class, 
org.apache.camel.util.json.JsonObject.class), this);
+        registry.addConverter(new TypeConvertible<>(groovy.util.Node.class, 
org.apache.camel.util.json.Jsonable.class), this);
+        registry.addConverter(new 
TypeConvertible<>(org.apache.groovy.json.internal.LazyMap.class, 
org.apache.camel.util.json.Jsonable.class), this);
+        registry.addConverter(new TypeConvertible<>(java.util.List.class, 
org.apache.camel.util.json.Jsonable.class), this);
+    }
+
+    public TypeConverter lookup(Class<?> to, Class<?> from) {
+        if (to == org.apache.camel.util.json.JsonArray.class) {
+            if (from == java.util.List.class) {
+                return this;
+            }
+        } else if (to == org.apache.camel.util.json.JsonObject.class) {
+            if (from == groovy.util.Node.class) {
+                return this;
+            }
+            if (from == org.apache.groovy.json.internal.LazyMap.class) {
+                return this;
+            }
+        } else if (to == org.apache.camel.util.json.Jsonable.class) {
+            if (from == groovy.util.Node.class) {
+                return this;
+            }
+            if (from == org.apache.groovy.json.internal.LazyMap.class) {
+                return this;
+            }
+            if (from == java.util.List.class) {
+                return this;
+            }
+        }
+        return null;
+    }
+
+}
diff --git 
a/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
 
b/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
new file mode 100644
index 000000000000..3b5b6a8c4acd
--- /dev/null
+++ 
b/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+org.apache.camel.groovy.json.GroovyJsonBulkConverterLoader
diff --git 
a/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/GroovyJsonConverter.java
 
b/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/GroovyJsonConverter.java
new file mode 100644
index 000000000000..795d6aece289
--- /dev/null
+++ 
b/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/GroovyJsonConverter.java
@@ -0,0 +1,68 @@
+/*
+ * 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.groovy.json;
+
+import java.util.List;
+
+import groovy.util.Node;
+import org.apache.camel.Converter;
+import org.apache.camel.Exchange;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsonable;
+import org.apache.groovy.json.internal.LazyMap;
+
+@Converter(generateBulkLoader = true)
+public class GroovyJsonConverter {
+
+    /**
+     * Utility classes should not have a public constructor.
+     */
+    private GroovyJsonConverter() {
+    }
+
+    @Converter(order = 1)
+    public static JsonObject convertToJsonObject(Node node, Exchange exchange) 
throws Exception {
+        return NodeToJsonHelper.nodeToJson(node);
+    }
+
+    @Converter(order = 2)
+    public static Jsonable convertToJson(Node node, Exchange exchange) throws 
Exception {
+        return NodeToJsonHelper.nodeToJson(node);
+    }
+
+    @Converter(order = 3)
+    public static JsonObject convertToJsonObject(LazyMap node, Exchange 
exchange) throws Exception {
+        return new JsonObject(node);
+    }
+
+    @Converter(order = 4)
+    public static JsonArray convertToJsonArray(List<?> node, Exchange 
exchange) throws Exception {
+        return new JsonArray(node);
+    }
+
+    @Converter(order = 5)
+    public static Jsonable convertToJson(LazyMap node, Exchange exchange) 
throws Exception {
+        return new JsonObject(node);
+    }
+
+    @Converter(order = 6)
+    public static Jsonable convertToJson(List<?> node, Exchange exchange) 
throws Exception {
+        return new JsonArray(node);
+    }
+
+}
diff --git 
a/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonArrayOnlyTest.java
 
b/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonArrayOnlyTest.java
new file mode 100644
index 000000000000..bd3dfbeb3770
--- /dev/null
+++ 
b/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonArrayOnlyTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.groovy.json;
+
+import java.util.List;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+public class GroovySimpleJSonArrayOnlyTest extends CamelTestSupport {
+
+    private static final String ARRAY_ONLY
+            = """
+                    [ "Red", "Green", "Blue" ]
+                    """;
+
+    @Test
+    public void testGroovySimpleJsonPath() throws Exception {
+        getMockEndpoint("mock:result").expectedMessageCount(1);
+        
getMockEndpoint("mock:result").message(0).body().isInstanceOf(List.class); // 
groovy json array
+        getMockEndpoint("mock:result").expectedHeaderReceived("c1", "Red");
+        getMockEndpoint("mock:result").expectedHeaderReceived("c2", "Green");
+        getMockEndpoint("mock:result").expectedHeaderReceived("c3", "Blue");
+
+        template.sendBody("direct:start", ARRAY_ONLY);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                        .unmarshal().groovyJson()
+                        .setHeader("c1", simple("${simpleJsonpath([0])}"))
+                        .setHeader("c2", simple("${simpleJsonpath([1])}"))
+                        .setHeader("c3", simple("${simpleJsonpath([2])}"))
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git 
a/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonArrayTest.java
 
b/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonArrayTest.java
new file mode 100644
index 000000000000..34daf8492989
--- /dev/null
+++ 
b/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonArrayTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.groovy.json;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.apache.groovy.json.internal.LazyMap;
+import org.junit.jupiter.api.Test;
+
+public class GroovySimpleJSonArrayTest extends CamelTestSupport {
+
+    private static final String COUNTRIES
+            = """
+                    {
+                      "countries": [ "Denmark", "Sweden", "Norway" ]
+                    }
+                    """;
+
+    @Test
+    public void testGroovySimpleJsonPath() throws Exception {
+        getMockEndpoint("mock:result").expectedMessageCount(1);
+        
getMockEndpoint("mock:result").message(0).body().isInstanceOf(LazyMap.class); 
// groovy json object
+        getMockEndpoint("mock:result").expectedHeaderReceived("c1", "Denmark");
+        getMockEndpoint("mock:result").expectedHeaderReceived("c2", "Sweden");
+        getMockEndpoint("mock:result").expectedHeaderReceived("c3", "Norway");
+
+        template.sendBody("direct:start", COUNTRIES);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                        .unmarshal().groovyJson()
+                        .setHeader("c1", 
simple("${simpleJsonpath(countries[0])}"))
+                        .setHeader("c2", 
simple("${simpleJsonpath(countries[1])}"))
+                        .setHeader("c3", 
simple("${simpleJsonpath(countries[2])}"))
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git 
a/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonTest.java
 
b/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonTest.java
new file mode 100644
index 000000000000..48f35358ad8f
--- /dev/null
+++ 
b/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovySimpleJSonTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.groovy.json;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.apache.groovy.json.internal.LazyMap;
+import org.junit.jupiter.api.Test;
+
+public class GroovySimpleJSonTest extends CamelTestSupport {
+
+    private static final String BOOKS
+            = """
+                    {
+                        "library": {
+                            "book": [
+                                {
+                                    "title": "No Title",
+                                    "author": "F. Scott Fitzgerald",
+                                    "year": "1925",
+                                    "genre": "Classic",
+                                    "id": "bk101"
+                                },
+                                {
+                                    "title": "1984",
+                                    "author": "George Orwell",
+                                    "year": "1949",
+                                    "genre": "Dystopian",
+                                    "id": "bk102"
+                                }
+                            ]
+                        }
+                    }
+                    """;
+
+    @Test
+    public void testGroovySimpleJsonPath() throws Exception {
+        getMockEndpoint("mock:result").expectedMessageCount(1);
+        
getMockEndpoint("mock:result").message(0).body().isInstanceOf(LazyMap.class); 
// groovy json object
+        getMockEndpoint("mock:result").expectedHeaderReceived("title1", "No 
Title");
+        getMockEndpoint("mock:result").expectedHeaderReceived("title2", 
"1984");
+
+        template.sendBody("direct:start", BOOKS);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                        .unmarshal().groovyJson()
+                        .setHeader("title1", 
simple("${simpleJsonpath(library.book[0].title)}"))
+                        .setHeader("title2", 
simple("${simpleJsonpath(library.book[1].title)}"))
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
index 38a2d575a9d6..81ff6c0225a7 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
@@ -72,7 +72,9 @@ import org.apache.camel.util.OgnlHelper;
 import org.apache.camel.util.SkipIterator;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.StringQuoteHelper;
+import org.apache.camel.util.json.JsonArray;
 import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsonable;
 
 /**
  * Expression builder used by the simple language.
@@ -3408,9 +3410,14 @@ public final class SimpleExpressionBuilder {
 
             @Override
             public Object evaluate(Exchange exchange) {
-                JsonObject jo = input.evaluate(exchange, JsonObject.class);
-                if (jo != null) {
+                Jsonable j = input.evaluate(exchange, Jsonable.class);
+                if (j instanceof JsonObject jo) {
                     return jo.path(path);
+                } else if (j instanceof JsonArray ja) {
+                    // wrap array in pseudo root to leverage json-path here
+                    JsonObject jo = new JsonObject();
+                    jo.put("_root_", ja);
+                    return jo.path("_root_." + path);
                 }
                 return null;
             }
diff --git 
a/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java
 
b/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java
index 9cfce48e9924..d361e0b05179 100644
--- 
a/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java
+++ 
b/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java
@@ -23,6 +23,7 @@ import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
@@ -146,7 +147,7 @@ public class JsonObject extends LinkedHashMap<String, 
Object> implements Jsonabl
         Object answer = null;
 
         boolean optional = path.startsWith("?");
-        JsonObject jo = this;
+        Map jo = this;
         String sub = path;
         if (optional && !path.contains(".") && !path.contains("[")) {
             sub = sub.substring(1);
@@ -161,8 +162,8 @@ public class JsonObject extends LinkedHashMap<String, 
Object> implements Jsonabl
             java.util.Optional<Object> o = doPath(path.substring(0, pos));
             if (o.isPresent()) {
                 answer = o.get();
-                if (answer instanceof JsonObject) {
-                    jo = (JsonObject) answer;
+                if (answer instanceof Map) {
+                    jo = (Map) answer;
                 }
             } else {
                 optional = true;
@@ -173,13 +174,34 @@ public class JsonObject extends LinkedHashMap<String, 
Object> implements Jsonabl
             java.util.Optional<Object> o = doPath(path);
             if (o.isPresent()) {
                 answer = o.get();
-                if (answer instanceof JsonObject) {
-                    jo = (JsonObject) answer;
+                if (answer instanceof Map) {
+                    jo = (Map) answer;
                 }
             } else {
                 optional = true;
             }
         }
+
+        // last part can be an index
+        if (sub.startsWith("[")) {
+            int pos = -1;
+            String num = sub.substring(1, sub.length() - 1);
+            if ("last".equals(num)) {
+                pos = Integer.MAX_VALUE;
+            } else {
+                pos = Integer.parseInt(num);
+            }
+            if (pos != -1 && answer instanceof List<?> arr) {
+                jo = null;
+                if (pos == Integer.MAX_VALUE) {
+                    answer = arr.getLast();
+                } else if (pos < arr.size()) {
+                    answer = arr.get(pos);
+                } else {
+                    answer = null;
+                }
+            }
+        }
         if (jo != null) {
             answer = jo.get(sub);
         }
@@ -233,12 +255,12 @@ public class JsonObject extends LinkedHashMap<String, 
Object> implements Jsonabl
                 }
                 part = part.substring(0, part.lastIndexOf('['));
             }
-            if (answer instanceof JsonObject jo) {
-                answer = pos == -1 ? jo.getMap(part) : jo.getJsonArray(part);
+            if (answer instanceof Map jo) {
+                answer = jo.get(part);
             } else {
-                answer = pos == -1 ? getMap(part) : getJsonArray(part);
+                answer = get(part);
             }
-            if (pos != -1 && answer instanceof JsonArray arr) {
+            if (pos != -1 && answer instanceof List<?> arr) {
                 if (pos == Integer.MAX_VALUE) {
                     answer = arr.getLast();
                 } else if (pos < arr.size()) {
diff --git 
a/tooling/camel-util-json/src/test/java/org/apache/camel/util/json/JsonObjectPathTest.java
 
b/tooling/camel-util-json/src/test/java/org/apache/camel/util/json/JsonObjectPathTest.java
index cea128dbb011..7d3498797fb9 100644
--- 
a/tooling/camel-util-json/src/test/java/org/apache/camel/util/json/JsonObjectPathTest.java
+++ 
b/tooling/camel-util-json/src/test/java/org/apache/camel/util/json/JsonObjectPathTest.java
@@ -56,6 +56,11 @@ public class JsonObjectPathTest {
                     }
                     """;
 
+    private static final String ARRAY_ONLY
+            = """
+                    [ "Red", "Green", "Blue" ]
+                    """;
+
     @Test
     public void testPath() throws Exception {
         JsonObject jo = (JsonObject) Jsoner.deserialize(BOOKS);
@@ -172,4 +177,28 @@ public class JsonObjectPathTest {
         }
     }
 
+    @Test
+    public void testPathArrayOnly() throws Exception {
+        JsonArray jo = (JsonArray) Jsoner.deserialize(ARRAY_ONLY);
+        Assertions.assertNotNull(jo);
+        Assertions.assertEquals(3, jo.size());
+
+        // wrap in root
+        JsonObject wrap = new JsonObject();
+        wrap.put("_root_", jo);
+
+        Assertions.assertEquals("Red", wrap.path("_root_.[0]"));
+        Assertions.assertEquals("Green", wrap.path("_root_.[1]"));
+        Assertions.assertEquals("Blue", wrap.path("_root_.[2]"));
+        Assertions.assertEquals("Blue", wrap.path("_root_.[last]"));
+        Assertions.assertNull(wrap.path("_root_?.[3]"));
+        try {
+            wrap.path("_root_.[3]");
+            fail();
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+    }
+
 }

Reply via email to