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 206f7ecd42d3 CAMEL-25928: camel-catalog - the resultType of a language 
and the type of convertBodyTo name the class of the body (#28435)
206f7ecd42d3 is described below

commit 206f7ecd42d305ff17ba8408181ef6abf7d1af70
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Oct 25 12:05:00 2026 +0100

    CAMEL-25928: camel-catalog - the resultType of a language and the type of 
convertBodyTo name the class of the body (#28435)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
---
 .../org/apache/camel/catalog/languages/bean.json   |   2 +-
 .../apache/camel/catalog/languages/constant.json   |   2 +-
 .../apache/camel/catalog/languages/datasonnet.json |   2 +-
 .../org/apache/camel/catalog/languages/file.json   |   2 +-
 .../org/apache/camel/catalog/languages/groovy.json |   2 +-
 .../apache/camel/catalog/languages/hl7terser.json  |   2 +-
 .../org/apache/camel/catalog/languages/jactl.json  |   2 +-
 .../org/apache/camel/catalog/languages/java.json   |   2 +-
 .../org/apache/camel/catalog/languages/jq.json     |   2 +-
 .../org/apache/camel/catalog/languages/js.json     |   2 +-
 .../apache/camel/catalog/languages/jsonpath.json   |   2 +-
 .../org/apache/camel/catalog/languages/mvel.json   |   2 +-
 .../org/apache/camel/catalog/languages/ognl.json   |   2 +-
 .../org/apache/camel/catalog/languages/python.json |   2 +-
 .../apache/camel/catalog/languages/python3.json    |   2 +-
 .../apache/camel/catalog/languages/quickjs.json    |   2 +-
 .../org/apache/camel/catalog/languages/ref.json    |   2 +-
 .../org/apache/camel/catalog/languages/simple.json |   2 +-
 .../org/apache/camel/catalog/languages/spel.json   |   2 +-
 .../org/apache/camel/catalog/languages/xpath.json  |   2 +-
 .../org/apache/camel/catalog/languages/xquery.json |   2 +-
 .../apache/camel/catalog/models/convertBodyTo.json |   2 +-
 .../org/apache/camel/language/bean/bean.json       |   2 +-
 .../apache/camel/language/bean/BeanLanguage.java   |   3 +-
 .../camel/language/datasonnet/datasonnet.json      |   2 +-
 .../language/datasonnet/DatasonnetLanguage.java    |   6 +-
 .../org/apache/camel/language/groovy/groovy.json   |   2 +-
 .../camel/language/groovy/GroovyLanguage.java      |   3 +-
 .../org/apache/camel/component/hl7/hl7terser.json  |   2 +-
 .../camel/component/hl7/Hl7TerserLanguage.java     |   2 +-
 .../org/apache/camel/language/jactl/jactl.json     |   2 +-
 .../apache/camel/language/jactl/JactlLanguage.java |   3 +-
 .../META-INF/org/apache/camel/language/js/js.json  |   2 +-
 .../camel/language/js/JavaScriptLanguage.java      |   1 +
 .../org/apache/camel/language/joor/java.json       |   2 +-
 .../apache/camel/language/joor/JavaLanguage.java   |   3 +-
 .../META-INF/org/apache/camel/language/jq/jq.json  |   2 +-
 .../org/apache/camel/language/jq/JqLanguage.java   |   3 +-
 .../org/apache/camel/jsonpath/jsonpath.json        |   2 +-
 .../apache/camel/jsonpath/JsonPathLanguage.java    |   1 +
 .../org/apache/camel/language/mvel/mvel.json       |   2 +-
 .../apache/camel/language/mvel/MvelLanguage.java   |   3 +-
 .../org/apache/camel/language/ognl/ognl.json       |   2 +-
 .../apache/camel/language/ognl/OgnlLanguage.java   |   3 +-
 .../org/apache/camel/language/python/python.json   |   2 +-
 .../camel/language/python/PythonLanguage.java      |   1 +
 .../org/apache/camel/language/python3/python3.json |   2 +-
 .../camel/language/python3/Python3Language.java    |   1 +
 .../org/apache/camel/language/quickjs/quickjs.json |   2 +-
 .../camel/language/quickjs/QuickjsLanguage.java    |   2 +-
 .../org/apache/camel/language/xquery/xquery.json   |   2 +-
 .../camel/language/xquery/XQueryLanguage.java      |   3 +-
 .../org/apache/camel/language/spel/spel.json       |   2 +-
 .../apache/camel/language/spel/SpelLanguage.java   |   1 +
 .../org/apache/camel/language/xpath/xpath.json     |   2 +-
 .../apache/camel/language/xpath/XPathLanguage.java |   3 +-
 .../java/org/apache/camel/spi/BodyType.java        |  11 ++
 .../apache/camel/language/constant/constant.json   |   2 +-
 .../org/apache/camel/language/ref/ref.json         |   2 +-
 .../org/apache/camel/language/simple/file.json     |   2 +-
 .../org/apache/camel/language/simple/simple.json   |   2 +-
 .../camel/language/constant/ConstantLanguage.java  |   3 +-
 .../org/apache/camel/language/ref/RefLanguage.java |   1 +
 .../apache/camel/language/simple/FileLanguage.java |   1 +
 .../camel/language/simple/SimpleLanguage.java      |   1 +
 .../org/apache/camel/model/convertBodyTo.json      |   2 +-
 .../apache/camel/model/ConvertBodyDefinition.java  |  15 +--
 .../apache/camel/processor/EipBodyTypesTest.java   |  34 ++++--
 docs/components/modules/ROOT/examples/js/camel.js  |   6 +-
 .../modules/ROOT/pages/camel-catalog.adoc          |  23 +++-
 .../dsl/jbang/core/commands/ai/CatalogDocs.java    |   8 +-
 .../jbang/core/commands/ai/CatalogDocsTest.java    |  10 +-
 .../apache/camel/tooling/model/BodyTypeModel.java  |  91 ++++++++++++++++
 .../org/apache/camel/tooling/model/JsonMapper.java |   4 +-
 .../apache/camel/tooling/model/JsonMapperTest.java |  41 ++++++++
 .../camel/maven/packaging/BodyTypesHelper.java     |  33 +++++-
 .../BodyTypesHelperJavaTypeOptionTest.java         | 116 +++++++++++++++++++++
 .../main/java/org/apache/camel/spi/BodyType.java   |  11 ++
 78 files changed, 452 insertions(+), 87 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/bean.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/bean.json
index 2324355c75a4..915628493d9a 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/bean.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/bean.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The first 
parameter of the method gets the body, converted to its type" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
method returns; null for a void method" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the method returns; null for a void method" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/constant.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/constant.json
index 9889e6d5b957..2d7c401f9705 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/constant.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/constant.json
@@ -16,7 +16,7 @@
     "modelJavaType": "org.apache.camel.model.language.ConstantExpression"
   },
   "bodyTypes": {
-    "expressionOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"dependsOn": [ "resultType" ], "description": "The text as it is written; 
resource:classpath:name loads the text of the resource" }
+    "expressionOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"javaTypeOption": "resultType", "description": "The text as it is written; 
resource:classpath:name loads the text of the resource" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/datasonnet.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/datasonnet.json
index 949646321217..a069ffdc0c65 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/datasonnet.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/datasonnet.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "dependsOn": [ "bodyMediaType", 
"source" ], "description": "The body as it is, in the variable body. JSON, XML 
or CSV text is read in that format only with bodyMediaType or a Content-Type 
header, and without them a stream is read as text" },
-    "expressionOut": { "carriers": [ "pojo", "null" ], "javaType": 
"com.datasonnet.document.Document", "dependsOn": [ "resultType", 
"outputMediaType" ], "description": "A Document with the result: a Java object, 
or text in outputMediaType when it is set, and null when the result is null. 
With resultType, the result converted to that type" }
+    "expressionOut": { "carriers": [ "pojo", "null" ], "javaType": 
"com.datasonnet.document.Document", "dependsOn": [ "outputMediaType" ], 
"javaTypeOption": "resultType", "description": "A Document with the result: a 
Java object, or text in outputMediaType when it is set, and null when the 
result is null" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json
index f74414f15283..658615747732 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, for ${body}: the file functions read the headers the file consumers set" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "A text with 
functions gives text, such as a file name. A single function gives its value as 
it is: ${file:size}, ${file:length} and ${file:modified} a Long, 
${file:absolute} a Boolean, the other file functions text, and null without the 
headers of a file" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "A text with functions gives text, such as a file 
name. A single function gives its value as it is: ${file:size}, ${file:length} 
and ${file:modified} a Long, ${file:absolute} a Boolean, the other file 
functions text, and null without the headers of a file" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/groovy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/groovy.json
index fd58e1de9825..4d8b86585629 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/groovy.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/groovy.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/hl7terser.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/hl7terser.json
index 4cecff9759b4..963854c0bb98 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/hl7terser.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/hl7terser.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" 
], "format": "hl7", "dependsOn": [ "source" ], "description": "An HL7 message 
as text or bytes, in ER7 or XML, a stream or a file of it, read in the charset 
of MSH-18, a HAPI Message, or a DOM of HL7 XML. Another body fails" },
-    "expressionOut": { "carriers": [ "text", "null" ], "javaType": 
"java.lang.String", "dependsOn": [ "resultType" ], "description": "The value of 
the field as text, null when the field is empty" }
+    "expressionOut": { "carriers": [ "text", "null" ], "javaType": 
"java.lang.String", "javaTypeOption": "resultType", "description": "The value 
of the field as text, null when the field is empty" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jactl.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jactl.json
index 056fbdec476e..8136e78c1f24 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jactl.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jactl.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body. Without host access a script uses text, a number, 
bytes, a Map or a List, not the methods of other objects: JSON text is not 
parsed" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/java.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/java.json
index d6bd93b95112..836005d10620 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/java.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/java.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body of type Object: bodyAs(type) converts it" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jq.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jq.json
index 64157b0b27cf..9fc019fa6df5 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jq.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jq.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "stream", "file", "map" 
], "format": "json", "dependsOn": [ "source" ], "description": "JSON as text, 
bytes, a stream or a file, or a Map" },
-    "expressionOut": { "carriers": [ "pojo", "list", "null" ], "dependsOn": [ 
"resultType" ], "description": "A JsonNode; a List of JsonNode when the filter 
gives several, null when it gives none" }
+    "expressionOut": { "carriers": [ "pojo", "list", "null" ], 
"javaTypeOption": "resultType", "description": "A JsonNode; a List of JsonNode 
when the filter gives several, null when it gives none" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/js.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/js.json
index 17c410e60c2b..ec9e48d5b372 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/js.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/js.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body: a String is a JavaScript string, and other Java 
objects keep their methods" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns: an object as a Map, an array or a typed array as a List, a Set 
as a Set, an ArrayBuffer as bytes and a Date as an Instant. A function fails" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns: an object as a Map, an 
array or a typed array as a List, a Set as a Set, an ArrayBuffer as bytes and a 
Date as an Instant. A function fails" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jsonpath.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jsonpath.json
index e3aeffd210b3..7b73e3571512 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jsonpath.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/jsonpath.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "JSON as text, 
bytes, a stream or a file, or parsed: a Map or a List. A POJO is read through 
Jackson" },
-    "expressionOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"writeAsString", "value": "true", "carriers": [ "text", "list" ] } ], 
"description": "The value the path selects: a Map for an object, a List for an 
array or for a path with a wildcard or a filter, otherwise text, a number or a 
boolean" }
+    "expressionOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"writeAsString", "value": "true", "carriers": [ "text", "list" ] } ], 
"javaTypeOption": "resultType", "description": "The value the path selects: a 
Map for an object, a List for an array or for a path with a wildcard or a 
filter, otherwise text, a number or a boolean" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/mvel.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/mvel.json
index 6b133a1c347e..4f4b874f7b5c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/mvel.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/mvel.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in request.body or message.body: there is no variable body" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
expression returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the expression returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/ognl.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/ognl.json
index 33c223028370..92f5e806328a 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/ognl.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/ognl.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in message.body or request.body: there is no variable body" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
expression returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the expression returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/python.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/python.json
index 9f2e6f91931a..082095205fee 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/python.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/python.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body: a String is a Python unicode string, and other Java 
objects keep their methods" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "The Java 
value of what the script returns: a dict as a Map, a list or a tuple as a List, 
a set as a Set, and None as null" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "The Java value of what the script returns: a dict 
as a Map, a list or a tuple as a List, a set as a Set, and None as null" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/python3.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/python3.json
index 7fd5d897b4ae..143c4ce904cc 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/python3.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/python3.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body: a Map, a List or an array can be indexed, and other 
Java objects have no methods unless the language is created with 
createWithHostAccess()" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns: a dict as a Map, a list or a tuple as a List, a set as a Set, 
bytes as bytes, and None as null. A function fails" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns: a dict as a Map, a list 
or a tuple as a List, a set as a Set, bytes as bytes, and None as null. A 
function fails" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/quickjs.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/quickjs.json
index 9ad3742d017c..cf97dffcb545 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/quickjs.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/quickjs.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "value", "map", "list", 
"pojo" ], "description": "A JSON copy of the body, in the variable body: bytes 
as Base64 text, and a POJO through Jackson. A stream fails: convert it to text 
first" },
-    "expressionOut": { "carriers": [ "text", "value", "map", "list", "null" ], 
"dependsOn": [ "resultType" ], "description": "The JSON value the script 
returns: an object or a Map as a Map, an array, a Set or a typed array as a 
List, a Date as its ISO text, and undefined, NaN or a function as null" }
+    "expressionOut": { "carriers": [ "text", "value", "map", "list", "null" ], 
"javaTypeOption": "resultType", "description": "The JSON value the script 
returns: an object or a Map as a Map, an array, a Set or a typed array as a 
List, a Date as its ISO text, and undefined, NaN or a function as null" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/ref.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/ref.json
index 18e2d383e073..693f64812763 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/ref.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/ref.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "As the expression 
or the predicate in the registry reads it" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
expression in the registry returns; a Boolean for a predicate" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the expression in the registry returns; a 
Boolean for a predicate" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
index 564822933793..78e1599a5d62 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ] },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "A text with 
functions gives text. A single function, such as ${body} or ${header.foo}, 
gives its value as it is" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "A text with functions gives text. A single 
function, such as ${body} or ${header.foo}, gives its value as it is" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/spel.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/spel.json
index ef218b49f9b7..bf3455968078 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/spel.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/spel.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in body, request.body or message.body" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
expression returns, and text when text surrounds the #{ } parts" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the expression returns, and text when text 
surrounds the #{ } parts" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xpath.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xpath.json
index 052b58d798f5..677ca8f5a162 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xpath.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xpath.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" 
], "format": "xml", "dependsOn": [ "source" ], "description": "XML as text, 
bytes, a stream or a file, or a DOM" },
-    "expressionOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.NodeList", "dependsOn": [ "resultType" ], "byOption": [ { 
"option": "resultQName", "value": "STRING", "carriers": [ "text" ], "javaType": 
"java.lang.String" }, { "option": "resultQName", "value": "NUMBER", "carriers": 
[ "value" ], "javaType": "java.lang.Double" }, { "option": "resultQName", 
"value": "BOOLEAN", "carriers": [ "value" ], "javaType": "java.lang.Boolean" }, 
{ "option": "resultQName", "value": "NODE", "car [...]
+    "expressionOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.NodeList", "byOption": [ { "option": "resultQName", "value": 
"STRING", "carriers": [ "text" ], "javaType": "java.lang.String" }, { "option": 
"resultQName", "value": "NUMBER", "carriers": [ "value" ], "javaType": 
"java.lang.Double" }, { "option": "resultQName", "value": "BOOLEAN", 
"carriers": [ "value" ], "javaType": "java.lang.Boolean" }, { "option": 
"resultQName", "value": "NODE", "carriers": [ "pojo" ], "javaType": [...]
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xquery.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xquery.json
index f136ec5a4217..82d7b8594ef6 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xquery.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/xquery.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" 
], "format": "xml", "dependsOn": [ "source" ], "description": "XML as text, 
bytes, a stream or a file, or a DOM or another javax.xml.transform.Source. A 
Map or no body fails" },
-    "expressionOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.Document", "dependsOn": [ "resultType" ], "description": "The 
result of the query as a DOM Document. A query that gives text, a number or 
more than one element fails unless resultType is java.lang.String" }
+    "expressionOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.Document", "javaTypeOption": "resultType", "description": "The 
result of the query as a DOM Document. A query that gives text, a number or 
more than one element fails unless resultType is java.lang.String" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertBodyTo.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertBodyTo.json
index 02ac5ed2a8f1..797bbfb78f52 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertBodyTo.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertBodyTo.json
@@ -21,6 +21,6 @@
     "charset": { "index": 6, "kind": "attribute", "displayName": "Charset", 
"group": "advanced", "label": "advanced", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a specific charset when converting." }
   },
   "bodyTypes": {
-    "eipOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "type", 
"value": "String", "carriers": [ "text" ], "javaType": "java.lang.String" }, { 
"option": "type", "value": "java.lang.String", "carriers": [ "text" ], 
"javaType": "java.lang.String" }, { "option": "type", "value": "byte[]", 
"carriers": [ "bytes" ], "javaType": "byte[]" }, { "option": "type", "value": 
"java.io.InputStream", "carriers": [ "stream" ], "javaType": 
"java.io.InputStream" }, { "option": "type", "value": [...]
+    "eipOut": { "carriers": [ "unknown" ], "javaTypeOption": "type", 
"description": "An object of the type the type option names; null when there is 
no conversion and mandatory is false" }
   }
 }
diff --git 
a/components/camel-bean/src/generated/resources/META-INF/org/apache/camel/language/bean/bean.json
 
b/components/camel-bean/src/generated/resources/META-INF/org/apache/camel/language/bean/bean.json
index 2324355c75a4..915628493d9a 100644
--- 
a/components/camel-bean/src/generated/resources/META-INF/org/apache/camel/language/bean/bean.json
+++ 
b/components/camel-bean/src/generated/resources/META-INF/org/apache/camel/language/bean/bean.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The first 
parameter of the method gets the body, converted to its type" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
method returns; null for a void method" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the method returns; null for a void method" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
 
b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
index ef566d0bc63e..041243144ff6 100644
--- 
a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
+++ 
b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
@@ -62,7 +62,8 @@ import org.apache.camel.util.URISupport;
 @org.apache.camel.spi.annotations.Language("bean")
 @BodyTypes(expressionIn = @BodyType(value = Carrier.ANY,
                                     description = "The first parameter of the 
method gets the body, converted to its type"),
-           expressionOut = @BodyType(value = Carrier.UNKNOWN, description = 
"What the method returns; null for a void method"))
+           expressionOut = @BodyType(value = Carrier.UNKNOWN, javaTypeOption = 
"resultType",
+                                     description = "What the method returns; 
null for a void method"))
 public class BeanLanguage extends TypedLanguageSupport implements 
ScriptingLanguage, PropertyConfigurer, StaticService {
     public static final String LANGUAGE = "bean";
 
diff --git 
a/components/camel-datasonnet/src/generated/resources/META-INF/org/apache/camel/language/datasonnet/datasonnet.json
 
b/components/camel-datasonnet/src/generated/resources/META-INF/org/apache/camel/language/datasonnet/datasonnet.json
index 949646321217..a069ffdc0c65 100644
--- 
a/components/camel-datasonnet/src/generated/resources/META-INF/org/apache/camel/language/datasonnet/datasonnet.json
+++ 
b/components/camel-datasonnet/src/generated/resources/META-INF/org/apache/camel/language/datasonnet/datasonnet.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "dependsOn": [ "bodyMediaType", 
"source" ], "description": "The body as it is, in the variable body. JSON, XML 
or CSV text is read in that format only with bodyMediaType or a Content-Type 
header, and without them a stream is read as text" },
-    "expressionOut": { "carriers": [ "pojo", "null" ], "javaType": 
"com.datasonnet.document.Document", "dependsOn": [ "resultType", 
"outputMediaType" ], "description": "A Document with the result: a Java object, 
or text in outputMediaType when it is set, and null when the result is null. 
With resultType, the result converted to that type" }
+    "expressionOut": { "carriers": [ "pojo", "null" ], "javaType": 
"com.datasonnet.document.Document", "dependsOn": [ "outputMediaType" ], 
"javaTypeOption": "resultType", "description": "A Document with the result: a 
Java object, or text in outputMediaType when it is set, and null when the 
result is null" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-datasonnet/src/main/java/org/apache/camel/language/datasonnet/DatasonnetLanguage.java
 
b/components/camel-datasonnet/src/main/java/org/apache/camel/language/datasonnet/DatasonnetLanguage.java
index 4039324db5f4..2b93ef4cb60f 100644
--- 
a/components/camel-datasonnet/src/main/java/org/apache/camel/language/datasonnet/DatasonnetLanguage.java
+++ 
b/components/camel-datasonnet/src/main/java/org/apache/camel/language/datasonnet/DatasonnetLanguage.java
@@ -46,10 +46,10 @@ import org.slf4j.LoggerFactory;
                                                   + " that format only with 
bodyMediaType or a Content-Type header, and"
                                                   + " without them a stream is 
read as text"),
            expressionOut = @BodyType(value = { Carrier.POJO, Carrier.NULL }, 
javaType = "com.datasonnet.document.Document",
-                                     dependsOn = { "resultType", 
"outputMediaType" },
+                                     dependsOn = "outputMediaType",
+                                     javaTypeOption = "resultType",
                                      description = "A Document with the 
result: a Java object, or text in outputMediaType"
-                                                   + " when it is set, and 
null when the result is null. With resultType, the"
-                                                   + " result converted to 
that type"))
+                                                   + " when it is set, and 
null when the result is null"))
 public class DatasonnetLanguage extends SingleInputTypedLanguageSupport {
     private static final Logger LOG = 
LoggerFactory.getLogger(DatasonnetLanguage.class);
     private final Map<String, String> classpathImports;
diff --git 
a/components/camel-groovy/src/generated/resources/META-INF/org/apache/camel/language/groovy/groovy.json
 
b/components/camel-groovy/src/generated/resources/META-INF/org/apache/camel/language/groovy/groovy.json
index fd58e1de9825..4d8b86585629 100644
--- 
a/components/camel-groovy/src/generated/resources/META-INF/org/apache/camel/language/groovy/groovy.json
+++ 
b/components/camel-groovy/src/generated/resources/META-INF/org/apache/camel/language/groovy/groovy.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
 
b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
index 1fda88d90b5e..920371b357bb 100644
--- 
a/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
+++ 
b/components/camel-groovy/src/main/java/org/apache/camel/language/groovy/GroovyLanguage.java
@@ -53,7 +53,8 @@ import org.slf4j.LoggerFactory;
 
 @Language("groovy")
 @BodyTypes(expressionIn = @BodyType(value = Carrier.ANY, description = "The 
body as it is, in the variable body"),
-           expressionOut = @BodyType(value = Carrier.UNKNOWN, description = 
"What the script returns"))
+           expressionOut = @BodyType(value = Carrier.UNKNOWN, javaTypeOption = 
"resultType",
+                                     description = "What the script returns"))
 public class GroovyLanguage extends TypedLanguageSupport implements 
ScriptingLanguage, Service {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(GroovyLanguage.class);
diff --git 
a/components/camel-hl7/src/generated/resources/META-INF/org/apache/camel/component/hl7/hl7terser.json
 
b/components/camel-hl7/src/generated/resources/META-INF/org/apache/camel/component/hl7/hl7terser.json
index 4cecff9759b4..963854c0bb98 100644
--- 
a/components/camel-hl7/src/generated/resources/META-INF/org/apache/camel/component/hl7/hl7terser.json
+++ 
b/components/camel-hl7/src/generated/resources/META-INF/org/apache/camel/component/hl7/hl7terser.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" 
], "format": "hl7", "dependsOn": [ "source" ], "description": "An HL7 message 
as text or bytes, in ER7 or XML, a stream or a file of it, read in the charset 
of MSH-18, a HAPI Message, or a DOM of HL7 XML. Another body fails" },
-    "expressionOut": { "carriers": [ "text", "null" ], "javaType": 
"java.lang.String", "dependsOn": [ "resultType" ], "description": "The value of 
the field as text, null when the field is empty" }
+    "expressionOut": { "carriers": [ "text", "null" ], "javaType": 
"java.lang.String", "javaTypeOption": "resultType", "description": "The value 
of the field as text, null when the field is empty" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/Hl7TerserLanguage.java
 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/Hl7TerserLanguage.java
index fe251c9b8671..be01065eddcb 100644
--- 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/Hl7TerserLanguage.java
+++ 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/Hl7TerserLanguage.java
@@ -46,7 +46,7 @@ import org.apache.camel.util.ObjectHelper;
                                                   + " in the charset of 
MSH-18, a HAPI Message, or a DOM of HL7 XML. Another"
                                                   + " body fails"),
            expressionOut = @BodyType(value = { Carrier.TEXT, Carrier.NULL }, 
javaType = "java.lang.String",
-                                     dependsOn = "resultType",
+                                     javaTypeOption = "resultType",
                                      description = "The value of the field as 
text, null when the field is empty"))
 public class Hl7TerserLanguage extends SingleInputTypedLanguageSupport {
 
diff --git 
a/components/camel-jactl/src/generated/resources/META-INF/org/apache/camel/language/jactl/jactl.json
 
b/components/camel-jactl/src/generated/resources/META-INF/org/apache/camel/language/jactl/jactl.json
index 056fbdec476e..8136e78c1f24 100644
--- 
a/components/camel-jactl/src/generated/resources/META-INF/org/apache/camel/language/jactl/jactl.json
+++ 
b/components/camel-jactl/src/generated/resources/META-INF/org/apache/camel/language/jactl/jactl.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body. Without host access a script uses text, a number, 
bytes, a Map or a List, not the methods of other objects: JSON text is not 
parsed" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-jactl/src/main/java/org/apache/camel/language/jactl/JactlLanguage.java
 
b/components/camel-jactl/src/main/java/org/apache/camel/language/jactl/JactlLanguage.java
index 6aea3956ffd6..8c047ac33954 100644
--- 
a/components/camel-jactl/src/main/java/org/apache/camel/language/jactl/JactlLanguage.java
+++ 
b/components/camel-jactl/src/main/java/org/apache/camel/language/jactl/JactlLanguage.java
@@ -87,7 +87,8 @@ import org.apache.camel.support.TypedLanguageSupport;
                                     description = "The body as it is, in the 
variable body. Without host access a script uses"
                                                   + " text, a number, bytes, a 
Map or a List, not the methods of other objects:"
                                                   + " JSON text is not 
parsed"),
-           expressionOut = @BodyType(value = Carrier.UNKNOWN, description = 
"What the script returns"))
+           expressionOut = @BodyType(value = Carrier.UNKNOWN, javaTypeOption = 
"resultType",
+                                     description = "What the script returns"))
 public class JactlLanguage extends TypedLanguageSupport implements 
ScriptingLanguage {
 
     // Create a globals variable for use during compilation.
diff --git 
a/components/camel-javascript/src/generated/resources/META-INF/org/apache/camel/language/js/js.json
 
b/components/camel-javascript/src/generated/resources/META-INF/org/apache/camel/language/js/js.json
index 17c410e60c2b..ec9e48d5b372 100644
--- 
a/components/camel-javascript/src/generated/resources/META-INF/org/apache/camel/language/js/js.json
+++ 
b/components/camel-javascript/src/generated/resources/META-INF/org/apache/camel/language/js/js.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body: a String is a JavaScript string, and other Java 
objects keep their methods" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns: an object as a Map, an array or a typed array as a List, a Set 
as a Set, an ArrayBuffer as bytes and a Date as an Instant. A function fails" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns: an object as a Map, an 
array or a typed array as a List, a Set as a Set, an ArrayBuffer as bytes and a 
Date as an Instant. A function fails" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-javascript/src/main/java/org/apache/camel/language/js/JavaScriptLanguage.java
 
b/components/camel-javascript/src/main/java/org/apache/camel/language/js/JavaScriptLanguage.java
index 498e99a9d7b2..9ebc529f07b0 100644
--- 
a/components/camel-javascript/src/main/java/org/apache/camel/language/js/JavaScriptLanguage.java
+++ 
b/components/camel-javascript/src/main/java/org/apache/camel/language/js/JavaScriptLanguage.java
@@ -59,6 +59,7 @@ import org.graalvm.polyglot.Value;
                                     description = "The body as it is, in the 
variable body: a String is a JavaScript string,"
                                                   + " and other Java objects 
keep their methods"),
            expressionOut = @BodyType(value = Carrier.UNKNOWN,
+                                     javaTypeOption = "resultType",
                                      description = "What the script returns: 
an object as a Map, an array or a typed array as a"
                                                    + " List, a Set as a Set, 
an ArrayBuffer as bytes and a Date as an Instant."
                                                    + " A function fails"))
diff --git 
a/components/camel-joor/src/generated/resources/META-INF/org/apache/camel/language/joor/java.json
 
b/components/camel-joor/src/generated/resources/META-INF/org/apache/camel/language/joor/java.json
index d6bd93b95112..836005d10620 100644
--- 
a/components/camel-joor/src/generated/resources/META-INF/org/apache/camel/language/joor/java.json
+++ 
b/components/camel-joor/src/generated/resources/META-INF/org/apache/camel/language/joor/java.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body of type Object: bodyAs(type) converts it" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-joor/src/main/java/org/apache/camel/language/joor/JavaLanguage.java
 
b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JavaLanguage.java
index e568bebc2fff..88ed2fe83911 100644
--- 
a/components/camel-joor/src/main/java/org/apache/camel/language/joor/JavaLanguage.java
+++ 
b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JavaLanguage.java
@@ -43,7 +43,8 @@ import org.slf4j.LoggerFactory;
 @BodyTypes(expressionIn = @BodyType(value = Carrier.ANY,
                                     description = "The body as it is, in the 
variable body of type Object: bodyAs(type)"
                                                   + " converts it"),
-           expressionOut = @BodyType(value = Carrier.UNKNOWN, description = 
"What the script returns"))
+           expressionOut = @BodyType(value = Carrier.UNKNOWN, javaTypeOption = 
"resultType",
+                                     description = "What the script returns"))
 public class JavaLanguage extends TypedLanguageSupport implements 
ScriptingLanguage, StaticService {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(JavaLanguage.class);
diff --git 
a/components/camel-jq/src/generated/resources/META-INF/org/apache/camel/language/jq/jq.json
 
b/components/camel-jq/src/generated/resources/META-INF/org/apache/camel/language/jq/jq.json
index 64157b0b27cf..9fc019fa6df5 100644
--- 
a/components/camel-jq/src/generated/resources/META-INF/org/apache/camel/language/jq/jq.json
+++ 
b/components/camel-jq/src/generated/resources/META-INF/org/apache/camel/language/jq/jq.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "stream", "file", "map" 
], "format": "json", "dependsOn": [ "source" ], "description": "JSON as text, 
bytes, a stream or a file, or a Map" },
-    "expressionOut": { "carriers": [ "pojo", "list", "null" ], "dependsOn": [ 
"resultType" ], "description": "A JsonNode; a List of JsonNode when the filter 
gives several, null when it gives none" }
+    "expressionOut": { "carriers": [ "pojo", "list", "null" ], 
"javaTypeOption": "resultType", "description": "A JsonNode; a List of JsonNode 
when the filter gives several, null when it gives none" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
index 0e84f1abd372..c7aa54d1d87b 100644
--- 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
+++ 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
@@ -33,7 +33,8 @@ import 
org.apache.camel.support.SingleInputTypedLanguageSupport;
 @BodyTypes(expressionIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE, Carrier.MAP },
                                     format = "json", dependsOn = "source",
                                     description = "JSON as text, bytes, a 
stream or a file, or a Map"),
-           expressionOut = @BodyType(value = { Carrier.POJO, Carrier.LIST, 
Carrier.NULL }, dependsOn = "resultType",
+           expressionOut = @BodyType(value = { Carrier.POJO, Carrier.LIST, 
Carrier.NULL },
+                                     javaTypeOption = "resultType",
                                      description = "A JsonNode; a List of 
JsonNode when the filter gives several, null when it"
                                                    + " gives none"))
 public class JqLanguage extends SingleInputTypedLanguageSupport implements 
StaticService {
diff --git 
a/components/camel-jsonpath/src/generated/resources/META-INF/org/apache/camel/jsonpath/jsonpath.json
 
b/components/camel-jsonpath/src/generated/resources/META-INF/org/apache/camel/jsonpath/jsonpath.json
index e3aeffd210b3..7b73e3571512 100644
--- 
a/components/camel-jsonpath/src/generated/resources/META-INF/org/apache/camel/jsonpath/jsonpath.json
+++ 
b/components/camel-jsonpath/src/generated/resources/META-INF/org/apache/camel/jsonpath/jsonpath.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "JSON as text, 
bytes, a stream or a file, or parsed: a Map or a List. A POJO is read through 
Jackson" },
-    "expressionOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"writeAsString", "value": "true", "carriers": [ "text", "list" ] } ], 
"description": "The value the path selects: a Map for an object, a List for an 
array or for a path with a wildcard or a filter, otherwise text, a number or a 
boolean" }
+    "expressionOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"writeAsString", "value": "true", "carriers": [ "text", "list" ] } ], 
"javaTypeOption": "resultType", "description": "The value the path selects: a 
Map for an object, a List for an array or for a path with a wildcard or a 
filter, otherwise text, a number or a boolean" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
index 880b0bd42336..623825338ed1 100644
--- 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
+++ 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
@@ -41,6 +41,7 @@ import 
org.apache.camel.support.component.PropertyConfigurerSupport;
            expressionOut = @BodyType(value = Carrier.UNKNOWN,
                                      byOption = @BodyType.When(option = 
"writeAsString", value = "true",
                                                                carriers = { 
Carrier.TEXT, Carrier.LIST }),
+                                     javaTypeOption = "resultType",
                                      description = "The value the path 
selects: a Map for an object, a List for an array or"
                                                    + " for a path with a 
wildcard or a filter, otherwise text, a number or a"
                                                    + " boolean"))
diff --git 
a/components/camel-mvel/src/generated/resources/META-INF/org/apache/camel/language/mvel/mvel.json
 
b/components/camel-mvel/src/generated/resources/META-INF/org/apache/camel/language/mvel/mvel.json
index 6b133a1c347e..4f4b874f7b5c 100644
--- 
a/components/camel-mvel/src/generated/resources/META-INF/org/apache/camel/language/mvel/mvel.json
+++ 
b/components/camel-mvel/src/generated/resources/META-INF/org/apache/camel/language/mvel/mvel.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in request.body or message.body: there is no variable body" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
expression returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the expression returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-mvel/src/main/java/org/apache/camel/language/mvel/MvelLanguage.java
 
b/components/camel-mvel/src/main/java/org/apache/camel/language/mvel/MvelLanguage.java
index 6ba3f13c8e33..1f4e537a8cdd 100644
--- 
a/components/camel-mvel/src/main/java/org/apache/camel/language/mvel/MvelLanguage.java
+++ 
b/components/camel-mvel/src/main/java/org/apache/camel/language/mvel/MvelLanguage.java
@@ -37,7 +37,8 @@ import org.mvel2.MVEL;
 @BodyTypes(expressionIn = @BodyType(value = Carrier.ANY,
                                     description = "The body as it is, in 
request.body or message.body: there is no variable"
                                                   + " body"),
-           expressionOut = @BodyType(value = Carrier.UNKNOWN, description = 
"What the expression returns"))
+           expressionOut = @BodyType(value = Carrier.UNKNOWN, javaTypeOption = 
"resultType",
+                                     description = "What the expression 
returns"))
 public class MvelLanguage extends TypedLanguageSupport implements 
ScriptingLanguage {
 
     @Override
diff --git 
a/components/camel-ognl/src/generated/resources/META-INF/org/apache/camel/language/ognl/ognl.json
 
b/components/camel-ognl/src/generated/resources/META-INF/org/apache/camel/language/ognl/ognl.json
index 33c223028370..92f5e806328a 100644
--- 
a/components/camel-ognl/src/generated/resources/META-INF/org/apache/camel/language/ognl/ognl.json
+++ 
b/components/camel-ognl/src/generated/resources/META-INF/org/apache/camel/language/ognl/ognl.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in message.body or request.body: there is no variable body" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
expression returns" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the expression returns" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-ognl/src/main/java/org/apache/camel/language/ognl/OgnlLanguage.java
 
b/components/camel-ognl/src/main/java/org/apache/camel/language/ognl/OgnlLanguage.java
index 61051e29fc20..9901bd148673 100644
--- 
a/components/camel-ognl/src/main/java/org/apache/camel/language/ognl/OgnlLanguage.java
+++ 
b/components/camel-ognl/src/main/java/org/apache/camel/language/ognl/OgnlLanguage.java
@@ -34,7 +34,8 @@ import org.apache.camel.support.TypedLanguageSupport;
 @Language("ognl")
 @BodyTypes(expressionIn = @BodyType(value = Carrier.ANY,
                                     description = "The body as it is, in 
message.body or request.body: there is no variable body"),
-           expressionOut = @BodyType(value = Carrier.UNKNOWN, description = 
"What the expression returns"))
+           expressionOut = @BodyType(value = Carrier.UNKNOWN, javaTypeOption = 
"resultType",
+                                     description = "What the expression 
returns"))
 public class OgnlLanguage extends TypedLanguageSupport implements 
ScriptingLanguage {
 
     @Override
diff --git 
a/components/camel-python/src/generated/resources/META-INF/org/apache/camel/language/python/python.json
 
b/components/camel-python/src/generated/resources/META-INF/org/apache/camel/language/python/python.json
index 9f2e6f91931a..082095205fee 100644
--- 
a/components/camel-python/src/generated/resources/META-INF/org/apache/camel/language/python/python.json
+++ 
b/components/camel-python/src/generated/resources/META-INF/org/apache/camel/language/python/python.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body: a String is a Python unicode string, and other Java 
objects keep their methods" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "The Java 
value of what the script returns: a dict as a Map, a list or a tuple as a List, 
a set as a Set, and None as null" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "The Java value of what the script returns: a dict 
as a Map, a list or a tuple as a List, a set as a Set, and None as null" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-python/src/main/java/org/apache/camel/language/python/PythonLanguage.java
 
b/components/camel-python/src/main/java/org/apache/camel/language/python/PythonLanguage.java
index c3739da09eac..3d251b44b586 100644
--- 
a/components/camel-python/src/main/java/org/apache/camel/language/python/PythonLanguage.java
+++ 
b/components/camel-python/src/main/java/org/apache/camel/language/python/PythonLanguage.java
@@ -40,6 +40,7 @@ import org.python.util.PythonInterpreter;
                                     description = "The body as it is, in the 
variable body: a String is a Python unicode"
                                                   + " string, and other Java 
objects keep their methods"),
            expressionOut = @BodyType(value = Carrier.UNKNOWN,
+                                     javaTypeOption = "resultType",
                                      description = "The Java value of what the 
script returns: a dict as a Map, a list or a"
                                                    + " tuple as a List, a set 
as a Set, and None as null"))
 public class PythonLanguage extends TypedLanguageSupport implements 
ScriptingLanguage {
diff --git 
a/components/camel-python3/src/generated/resources/META-INF/org/apache/camel/language/python3/python3.json
 
b/components/camel-python3/src/generated/resources/META-INF/org/apache/camel/language/python3/python3.json
index 7fd5d897b4ae..143c4ce904cc 100644
--- 
a/components/camel-python3/src/generated/resources/META-INF/org/apache/camel/language/python3/python3.json
+++ 
b/components/camel-python3/src/generated/resources/META-INF/org/apache/camel/language/python3/python3.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in the variable body: a Map, a List or an array can be indexed, and other 
Java objects have no methods unless the language is created with 
createWithHostAccess()" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
script returns: a dict as a Map, a list or a tuple as a List, a set as a Set, 
bytes as bytes, and None as null. A function fails" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the script returns: a dict as a Map, a list 
or a tuple as a List, a set as a Set, bytes as bytes, and None as null. A 
function fails" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-python3/src/main/java/org/apache/camel/language/python3/Python3Language.java
 
b/components/camel-python3/src/main/java/org/apache/camel/language/python3/Python3Language.java
index 3fcac2e23ff7..7c6bf3c9d9df 100644
--- 
a/components/camel-python3/src/main/java/org/apache/camel/language/python3/Python3Language.java
+++ 
b/components/camel-python3/src/main/java/org/apache/camel/language/python3/Python3Language.java
@@ -79,6 +79,7 @@ import org.graalvm.polyglot.Value;
                                                   + " indexed, and other Java 
objects have no methods unless the language is"
                                                   + " created with 
createWithHostAccess()"),
            expressionOut = @BodyType(value = Carrier.UNKNOWN,
+                                     javaTypeOption = "resultType",
                                      description = "What the script returns: a 
dict as a Map, a list or a tuple as a List, a set"
                                                    + " as a Set, bytes as 
bytes, and None as null. A function fails"))
 public class Python3Language extends TypedLanguageSupport implements 
ScriptingLanguage, Service {
diff --git 
a/components/camel-quickjs/src/generated/resources/META-INF/org/apache/camel/language/quickjs/quickjs.json
 
b/components/camel-quickjs/src/generated/resources/META-INF/org/apache/camel/language/quickjs/quickjs.json
index 9ad3742d017c..cf97dffcb545 100644
--- 
a/components/camel-quickjs/src/generated/resources/META-INF/org/apache/camel/language/quickjs/quickjs.json
+++ 
b/components/camel-quickjs/src/generated/resources/META-INF/org/apache/camel/language/quickjs/quickjs.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "value", "map", "list", 
"pojo" ], "description": "A JSON copy of the body, in the variable body: bytes 
as Base64 text, and a POJO through Jackson. A stream fails: convert it to text 
first" },
-    "expressionOut": { "carriers": [ "text", "value", "map", "list", "null" ], 
"dependsOn": [ "resultType" ], "description": "The JSON value the script 
returns: an object or a Map as a Map, an array, a Set or a typed array as a 
List, a Date as its ISO text, and undefined, NaN or a function as null" }
+    "expressionOut": { "carriers": [ "text", "value", "map", "list", "null" ], 
"javaTypeOption": "resultType", "description": "The JSON value the script 
returns: an object or a Map as a Map, an array, a Set or a typed array as a 
List, a Date as its ISO text, and undefined, NaN or a function as null" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-quickjs/src/main/java/org/apache/camel/language/quickjs/QuickjsLanguage.java
 
b/components/camel-quickjs/src/main/java/org/apache/camel/language/quickjs/QuickjsLanguage.java
index d24a8eafdfb0..403081268943 100644
--- 
a/components/camel-quickjs/src/main/java/org/apache/camel/language/quickjs/QuickjsLanguage.java
+++ 
b/components/camel-quickjs/src/main/java/org/apache/camel/language/quickjs/QuickjsLanguage.java
@@ -64,7 +64,7 @@ import run.endive.runtime.Memory;
                                     description = "A JSON copy of the body, in 
the variable body: bytes as Base64 text, and a"
                                                   + " POJO through Jackson. A 
stream fails: convert it to text first"),
            expressionOut = @BodyType(value = { Carrier.TEXT, Carrier.VALUE, 
Carrier.MAP, Carrier.LIST, Carrier.NULL },
-                                     dependsOn = "resultType",
+                                     javaTypeOption = "resultType",
                                      description = "The JSON value the script 
returns: an object or a Map as a Map, an array, a"
                                                    + " Set or a typed array as 
a List, a Date as its ISO text, and undefined, NaN"
                                                    + " or a function as null"))
diff --git 
a/components/camel-saxon/src/generated/resources/META-INF/org/apache/camel/language/xquery/xquery.json
 
b/components/camel-saxon/src/generated/resources/META-INF/org/apache/camel/language/xquery/xquery.json
index f136ec5a4217..82d7b8594ef6 100644
--- 
a/components/camel-saxon/src/generated/resources/META-INF/org/apache/camel/language/xquery/xquery.json
+++ 
b/components/camel-saxon/src/generated/resources/META-INF/org/apache/camel/language/xquery/xquery.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" 
], "format": "xml", "dependsOn": [ "source" ], "description": "XML as text, 
bytes, a stream or a file, or a DOM or another javax.xml.transform.Source. A 
Map or no body fails" },
-    "expressionOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.Document", "dependsOn": [ "resultType" ], "description": "The 
result of the query as a DOM Document. A query that gives text, a number or 
more than one element fails unless resultType is java.lang.String" }
+    "expressionOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.Document", "javaTypeOption": "resultType", "description": "The 
result of the query as a DOM Document. A query that gives text, a number or 
more than one element fails unless resultType is java.lang.String" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
 
b/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
index 935afeb4fee6..3cb8faf10011 100644
--- 
a/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
+++ 
b/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
@@ -35,7 +35,8 @@ import 
org.apache.camel.support.component.PropertyConfigurerSupport;
                                     format = "xml", dependsOn = "source",
                                     description = "XML as text, bytes, a 
stream or a file, or a DOM or another"
                                                   + " 
javax.xml.transform.Source. A Map or no body fails"),
-           expressionOut = @BodyType(value = Carrier.POJO, javaType = 
"org.w3c.dom.Document", dependsOn = "resultType",
+           expressionOut = @BodyType(value = Carrier.POJO, javaType = 
"org.w3c.dom.Document",
+                                     javaTypeOption = "resultType",
                                      description = "The result of the query as 
a DOM Document. A query that gives text, a"
                                                    + " number or more than one 
element fails unless resultType is"
                                                    + " java.lang.String"))
diff --git 
a/components/camel-spring-parent/camel-spring/src/generated/resources/META-INF/org/apache/camel/language/spel/spel.json
 
b/components/camel-spring-parent/camel-spring/src/generated/resources/META-INF/org/apache/camel/language/spel/spel.json
index ef218b49f9b7..bf3455968078 100644
--- 
a/components/camel-spring-parent/camel-spring/src/generated/resources/META-INF/org/apache/camel/language/spel/spel.json
+++ 
b/components/camel-spring-parent/camel-spring/src/generated/resources/META-INF/org/apache/camel/language/spel/spel.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, in body, request.body or message.body" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
expression returns, and text when text surrounds the #{ } parts" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the expression returns, and text when text 
surrounds the #{ } parts" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/language/spel/SpelLanguage.java
 
b/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/language/spel/SpelLanguage.java
index da0dcf5bba99..45800dab49b4 100644
--- 
a/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/language/spel/SpelLanguage.java
+++ 
b/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/language/spel/SpelLanguage.java
@@ -38,6 +38,7 @@ import org.springframework.expression.BeanResolver;
 @BodyTypes(expressionIn = @BodyType(value = Carrier.ANY,
                                     description = "The body as it is, in body, 
request.body or message.body"),
            expressionOut = @BodyType(value = Carrier.UNKNOWN,
+                                     javaTypeOption = "resultType",
                                      description = "What the expression 
returns, and text when text surrounds the #{ } parts"))
 public class SpelLanguage extends TypedLanguageSupport implements 
StaticService {
 
diff --git 
a/components/camel-xpath/src/generated/resources/META-INF/org/apache/camel/language/xpath/xpath.json
 
b/components/camel-xpath/src/generated/resources/META-INF/org/apache/camel/language/xpath/xpath.json
index 052b58d798f5..677ca8f5a162 100644
--- 
a/components/camel-xpath/src/generated/resources/META-INF/org/apache/camel/language/xpath/xpath.json
+++ 
b/components/camel-xpath/src/generated/resources/META-INF/org/apache/camel/language/xpath/xpath.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" 
], "format": "xml", "dependsOn": [ "source" ], "description": "XML as text, 
bytes, a stream or a file, or a DOM" },
-    "expressionOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.NodeList", "dependsOn": [ "resultType" ], "byOption": [ { 
"option": "resultQName", "value": "STRING", "carriers": [ "text" ], "javaType": 
"java.lang.String" }, { "option": "resultQName", "value": "NUMBER", "carriers": 
[ "value" ], "javaType": "java.lang.Double" }, { "option": "resultQName", 
"value": "BOOLEAN", "carriers": [ "value" ], "javaType": "java.lang.Boolean" }, 
{ "option": "resultQName", "value": "NODE", "car [...]
+    "expressionOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.NodeList", "byOption": [ { "option": "resultQName", "value": 
"STRING", "carriers": [ "text" ], "javaType": "java.lang.String" }, { "option": 
"resultQName", "value": "NUMBER", "carriers": [ "value" ], "javaType": 
"java.lang.Double" }, { "option": "resultQName", "value": "BOOLEAN", 
"carriers": [ "value" ], "javaType": "java.lang.Boolean" }, { "option": 
"resultQName", "value": "NODE", "carriers": [ "pojo" ], "javaType": [...]
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
 
b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
index 67f5f2f174e0..8df683cba2c2 100644
--- 
a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
+++ 
b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
@@ -40,7 +40,7 @@ import 
org.apache.camel.support.component.PropertyConfigurerSupport;
 @BodyTypes(expressionIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE, Carrier.POJO },
                                     format = "xml", dependsOn = "source",
                                     description = "XML as text, bytes, a 
stream or a file, or a DOM"),
-           expressionOut = @BodyType(value = Carrier.POJO, javaType = 
"org.w3c.dom.NodeList", dependsOn = "resultType",
+           expressionOut = @BodyType(value = Carrier.POJO, javaType = 
"org.w3c.dom.NodeList",
                                      byOption = {
                                              @BodyType.When(option = 
"resultQName", value = "STRING", carriers = Carrier.TEXT,
                                                             javaType = 
"java.lang.String"),
@@ -50,6 +50,7 @@ import 
org.apache.camel.support.component.PropertyConfigurerSupport;
                                                             javaType = 
"java.lang.Boolean"),
                                              @BodyType.When(option = 
"resultQName", value = "NODE", carriers = Carrier.POJO,
                                                             javaType = 
"org.w3c.dom.Node") },
+                                     javaTypeOption = "resultType",
                                      description = "The nodes the expression 
selects"))
 public class XPathLanguage extends SingleInputTypedLanguageSupport implements 
PropertyConfigurer {
     private QName resultQName;
diff --git 
a/core/camel-api/src/generated/java/org/apache/camel/spi/BodyType.java 
b/core/camel-api/src/generated/java/org/apache/camel/spi/BodyType.java
index 5530d2317eb2..7f18b4d3460c 100644
--- a/core/camel-api/src/generated/java/org/apache/camel/spi/BodyType.java
+++ b/core/camel-api/src/generated/java/org/apache/camel/spi/BodyType.java
@@ -73,6 +73,17 @@ public @interface BodyType {
      */
     String from() default "";
 
+    /**
+     * The option that names the Java type of the body, such as {@code 
resultType} of a language, whose result is
+     * converted to the class the option names. When the option is set, and 
the options in {@link #dependsOn()} keep
+     * their default values, the body is of that class, or null when it does 
not convert; the bodies {@link #byOption()}
+     * gives for other options do not hold then. The carriers say the body 
when it is not set. The carrier follows the
+     * class: String is text, byte[] bytes, an InputStream or a Reader a 
stream, a File or a Path a file, a number, a
+     * boolean or a character a value, a Map map, a List, a Set, another 
Collection or an array list, an Iterator
+     * iterator, Object unknown, and any other class pojo.
+     */
+    String javaTypeOption() default "";
+
     /**
      * What to know about the body, in a sentence for the documentation and 
the tools.
      */
diff --git 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/constant/constant.json
 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/constant/constant.json
index 9889e6d5b957..2d7c401f9705 100644
--- 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/constant/constant.json
+++ 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/constant/constant.json
@@ -16,7 +16,7 @@
     "modelJavaType": "org.apache.camel.model.language.ConstantExpression"
   },
   "bodyTypes": {
-    "expressionOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"dependsOn": [ "resultType" ], "description": "The text as it is written; 
resource:classpath:name loads the text of the resource" }
+    "expressionOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"javaTypeOption": "resultType", "description": "The text as it is written; 
resource:classpath:name loads the text of the resource" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/ref/ref.json
 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/ref/ref.json
index 18e2d383e073..693f64812763 100644
--- 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/ref/ref.json
+++ 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/ref/ref.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "As the expression 
or the predicate in the registry reads it" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "What the 
expression in the registry returns; a Boolean for a predicate" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "What the expression in the registry returns; a 
Boolean for a predicate" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json
 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json
index f74414f15283..658615747732 100644
--- 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json
+++ 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ], "description": "The body as it 
is, for ${body}: the file functions read the headers the file consumers set" },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "A text with 
functions gives text, such as a file name. A single function gives its value as 
it is: ${file:size}, ${file:length} and ${file:modified} a Long, 
${file:absolute} a Boolean, the other file functions text, and null without the 
headers of a file" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "A text with functions gives text, such as a file 
name. A single function gives its value as it is: ${file:size}, ${file:length} 
and ${file:modified} a Long, ${file:absolute} a Boolean, the other file 
functions text, and null without the headers of a file" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
index 564822933793..78e1599a5d62 100644
--- 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
+++ 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
@@ -17,7 +17,7 @@
   },
   "bodyTypes": {
     "expressionIn": { "carriers": [ "any" ] },
-    "expressionOut": { "carriers": [ "unknown" ], "description": "A text with 
functions gives text. A single function, such as ${body} or ${header.foo}, 
gives its value as it is" }
+    "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": 
"resultType", "description": "A text with functions gives text. A single 
function, such as ${body} or ${header.foo}, gives its value as it is" }
   },
   "properties": {
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": 
"common", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
id of this node." },
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/constant/ConstantLanguage.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/constant/ConstantLanguage.java
index 738723733d01..5e071e173194 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/constant/ConstantLanguage.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/constant/ConstantLanguage.java
@@ -32,7 +32,8 @@ import org.apache.camel.support.builder.ExpressionBuilder;
  * A language for constant expressions.
  */
 @Language("constant")
-@BodyTypes(expressionOut = @BodyType(value = Carrier.TEXT, javaType = 
"java.lang.String", dependsOn = "resultType",
+@BodyTypes(expressionOut = @BodyType(value = Carrier.TEXT, javaType = 
"java.lang.String",
+                                     javaTypeOption = "resultType",
                                      description = "The text as it is written; 
resource:classpath:name loads the text of the"
                                                    + " resource"))
 public class ConstantLanguage extends LanguageSupport {
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/ref/RefLanguage.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/ref/RefLanguage.java
index 0f13f18fc5c0..bd35dffbdc57 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/ref/RefLanguage.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/ref/RefLanguage.java
@@ -38,6 +38,7 @@ import org.apache.camel.support.builder.ExpressionBuilder;
 @BodyTypes(expressionIn = @BodyType(value = Carrier.ANY,
                                     description = "As the expression or the 
predicate in the registry reads it"),
            expressionOut = @BodyType(value = Carrier.UNKNOWN,
+                                     javaTypeOption = "resultType",
                                      description = "What the expression in the 
registry returns; a Boolean for a predicate"))
 public class RefLanguage extends TypedLanguageSupport {
 
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/FileLanguage.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/FileLanguage.java
index 51c92bb2a8a5..b74521e242e8 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/FileLanguage.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/FileLanguage.java
@@ -29,6 +29,7 @@ import org.apache.camel.spi.annotations.Language;
                                     description = "The body as it is, for 
${body}: the file functions read the headers the file"
                                                   + " consumers set"),
            expressionOut = @BodyType(value = Carrier.UNKNOWN,
+                                     javaTypeOption = "resultType",
                                      description = "A text with functions 
gives text, such as a file name. A single function"
                                                    + " gives its value as it 
is: ${file:size}, ${file:length} and"
                                                    + " ${file:modified} a 
Long, ${file:absolute} a Boolean, the other file"
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
index a43ebbb47d4a..90fd6008a48d 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
@@ -45,6 +45,7 @@ import org.slf4j.LoggerFactory;
 @Language(value = "simple", functionsClass = SimpleConstants.class, 
operatorsClass = SimpleOperatorConstants.class)
 @BodyTypes(expressionIn = @BodyType(Carrier.ANY),
            expressionOut = @BodyType(value = Carrier.UNKNOWN,
+                                     javaTypeOption = "resultType",
                                      description = "A text with functions 
gives text. A single function, such as ${body} or"
                                                    + " ${header.foo}, gives 
its value as it is"))
 public class SimpleLanguage extends LanguageSupport implements StaticService {
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/convertBodyTo.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/convertBodyTo.json
index 02ac5ed2a8f1..797bbfb78f52 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/convertBodyTo.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/convertBodyTo.json
@@ -21,6 +21,6 @@
     "charset": { "index": 6, "kind": "attribute", "displayName": "Charset", 
"group": "advanced", "label": "advanced", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a specific charset when converting." }
   },
   "bodyTypes": {
-    "eipOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "type", 
"value": "String", "carriers": [ "text" ], "javaType": "java.lang.String" }, { 
"option": "type", "value": "java.lang.String", "carriers": [ "text" ], 
"javaType": "java.lang.String" }, { "option": "type", "value": "byte[]", 
"carriers": [ "bytes" ], "javaType": "byte[]" }, { "option": "type", "value": 
"java.io.InputStream", "carriers": [ "stream" ], "javaType": 
"java.io.InputStream" }, { "option": "type", "value": [...]
+    "eipOut": { "carriers": [ "unknown" ], "javaTypeOption": "type", 
"description": "An object of the type the type option names; null when there is 
no conversion and mandatory is false" }
   }
 }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertBodyDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertBodyDefinition.java
index 1564ab6da67f..e34f0e685158 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertBodyDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertBodyDefinition.java
@@ -35,20 +35,7 @@ import org.apache.camel.spi.annotations.DslArg;
           description = "Converts the message body to a specified Java type 
using Camel's built-in type converters")
 @XmlRootElement(name = "convertBodyTo")
 @XmlAccessorType(XmlAccessType.FIELD)
-@BodyTypes(eipOut = @BodyType(value = Carrier.UNKNOWN,
-                              byOption = {
-                                      @BodyType.When(option = "type", value = 
"String", carriers = Carrier.TEXT,
-                                                     javaType = 
"java.lang.String"),
-                                      @BodyType.When(option = "type", value = 
"java.lang.String", carriers = Carrier.TEXT,
-                                                     javaType = 
"java.lang.String"),
-                                      @BodyType.When(option = "type", value = 
"byte[]", carriers = Carrier.BYTES,
-                                                     javaType = "byte[]"),
-                                      @BodyType.When(option = "type", value = 
"java.io.InputStream", carriers = Carrier.STREAM,
-                                                     javaType = 
"java.io.InputStream"),
-                                      @BodyType.When(option = "type", value = 
"java.util.Map", carriers = Carrier.MAP,
-                                                     javaType = 
"java.util.Map"),
-                                      @BodyType.When(option = "type", value = 
"java.util.List", carriers = Carrier.LIST,
-                                                     javaType = 
"java.util.List") },
+@BodyTypes(eipOut = @BodyType(value = Carrier.UNKNOWN, javaTypeOption = "type",
                               description = "An object of the type the type 
option names; null when there is no conversion"
                                             + " and mandatory is false"))
 public class ConvertBodyDefinition extends 
NoOutputDefinition<ConvertBodyDefinition> {
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/EipBodyTypesTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/EipBodyTypesTest.java
index 92fdf6ff4991..343c6d37e6e2 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/EipBodyTypesTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/EipBodyTypesTest.java
@@ -38,6 +38,8 @@ import org.apache.camel.Route;
 import org.apache.camel.StreamCache;
 import org.apache.camel.builder.AggregationStrategies;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.language.constant.ConstantLanguage;
+import org.apache.camel.language.simple.SimpleLanguage;
 import org.apache.camel.model.AggregateDefinition;
 import org.apache.camel.model.CacheDefinition;
 import org.apache.camel.model.CatchDefinition;
@@ -81,6 +83,7 @@ import org.apache.camel.model.TransformDefinition;
 import org.apache.camel.model.TryDefinition;
 import org.apache.camel.model.ValidateDefinition;
 import org.apache.camel.model.WireTapDefinition;
+import org.apache.camel.model.language.ConstantExpression;
 import org.apache.camel.spi.BodyType;
 import org.apache.camel.spi.BodyType.Carrier;
 import org.apache.camel.spi.BodyTypes;
@@ -90,6 +93,7 @@ import org.junit.jupiter.api.Test;
 
 import static org.apache.camel.builder.Builder.body;
 import static org.apache.camel.builder.Builder.constant;
+import static org.apache.camel.builder.Builder.simple;
 import static org.awaitility.Awaitility.await;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -217,13 +221,23 @@ public class EipBodyTypesTest extends ContextTestSupport {
     }
 
     @Test
-    public void convertBodyToByType() throws Exception {
-        Exchange out = run(r -> r.convertBodyTo(String.class), 5);
-        assertByOption(ConvertBodyDefinition.class, "type", 
"java.lang.String", null, out.getMessage().getBody());
-        out = run(r -> r.convertBodyTo(byte[].class), "Hello");
-        assertByOption(ConvertBodyDefinition.class, "type", "byte[]", null, 
out.getMessage().getBody());
-        out = run(r -> r.convertBodyTo(List.class), new Object[] { "a" });
-        assertByOption(ConvertBodyDefinition.class, "type", "java.util.List", 
null, out.getMessage().getBody());
+    public void convertBodyToTheTypeOption() throws Exception {
+        assertEquals("type", 
bodyTypes(ConvertBodyDefinition.class).eipOut().javaTypeOption());
+        assertJavaType(run(r -> r.convertBodyTo(String.class), 5), 
String.class);
+        assertJavaType(run(r -> r.convertBodyTo(byte[].class), "Hello"), 
byte[].class);
+        assertJavaType(run(r -> r.convertBodyTo(List.class), new Object[] { 
"a" }), List.class);
+    }
+
+    @Test
+    public void theResultTypeOfTheLanguage() throws Exception {
+        // setBody and transform leave what their language gives, which is of 
the class its resultType names
+        assertEquals("resultType", 
bodyTypes(SimpleLanguage.class).expressionOut().javaTypeOption());
+        assertJavaType(run(r -> r.setBody(simple("${body}", Integer.class)), 
"5"), Integer.class);
+        assertJavaType(run(r -> r.transform(simple("${body}", byte[].class)), 
"Hello"), byte[].class);
+        assertEquals("resultType", 
bodyTypes(ConstantLanguage.class).expressionOut().javaTypeOption());
+        ConstantExpression five = new ConstantExpression("5");
+        five.setResultType(Long.class);
+        assertJavaType(run(r -> r.setBody(five), new Order()), Long.class);
     }
 
     // the checks of a side
@@ -281,6 +295,12 @@ public class EipBodyTypesTest extends ContextTestSupport {
         }
     }
 
+    private static void assertJavaType(Exchange out, Class<?> type) {
+        Object body = out.getMessage().getBody();
+        assertTrue(type.isInstance(body),
+                "the body is not a " + type.getName() + ", but " + (body != 
null ? body.getClass().getName() : null));
+    }
+
     private static void assertFrom(Class<?> model, String side) {
         assertEquals(side, bodyTypes(model).eipOut().from(), 
model.getSimpleName());
     }
diff --git a/docs/components/modules/ROOT/examples/js/camel.js 
b/docs/components/modules/ROOT/examples/js/camel.js
index 006d8481ac19..23135890c2ff 100644
--- a/docs/components/modules/ROOT/examples/js/camel.js
+++ b/docs/components/modules/ROOT/examples/js/camel.js
@@ -85,7 +85,8 @@ module.exports = {
     return words + (value.javaType ? ' (`' + value.javaType + '`)' : '') + 
(value.format ? ', as ' + value.format : '')
   },
 
-  // the description, the bodies for other values of an option, and the 
options the body depends on
+  // the description, the option that names the class of the body, the bodies 
for other values of an option, and the
+  // options the body depends on
   bodyDescription: (value) => {
     // only what reads as an attribute reference ({body}, not {header.foo}, 
which keeps a backslash), and the cell separator
     const escape = (text) => text.replace(/\{(\w[\w-]*)\}/g, 
'\\{$1}').split('|').join('\\|')
@@ -93,6 +94,9 @@ module.exports = {
     if (value.description) {
       parts.push(escape(value.description) + (value.description.endsWith('.') 
? '' : '.'))
     }
+    if (value.javaTypeOption) {
+      parts.push(`With \`${value.javaTypeOption}\` set: an object of the class 
it names, or null.`)
+    }
     if (value.byOption && value.byOption.length) {
       parts.push(value.byOption.map((option) => `* With 
\`${option.option}=${option.value}\`: `
         + module.exports.bodyCarriers(option)).join('\n'))
diff --git a/docs/user-manual/modules/ROOT/pages/camel-catalog.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-catalog.adoc
index bad15bbb7a15..23e4ea75e9e4 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-catalog.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-catalog.adoc
@@ -178,6 +178,24 @@ expression (`expressionOut`), and a `filter` what its own 
steps end with (`steps
 }
 ----
 
+An option that names the class of the body is the `javaTypeOption` of a side: 
the `resultType` of a language, whose
+result is converted to that class, and the `type` of `convertBodyTo`. When the 
option is set, the body is an object of
+the class it names, or null when it does not convert. That holds while the 
options the side depends on keep their
+defaults (an option that makes the body a collection of that class is one of 
them), and it wins over the bodies `byOption` gives
+for other options. The carrier follows the class: `String` is `text`, `byte[]` 
is `bytes`, an `InputStream` or a
+`Reader` is a `stream`, a `File` or a `Path` is a `file`, a number, a boolean 
or a character is a `value`, a `Map` is a
+`map`, a `Collection` or an array is a `list`, an `Iterator` is an `iterator`, 
`Object` is `unknown`, and any other
+class is a `pojo`. `BodyTypeModel.carrierOf` gives
+it for a class name, also for the short names Camel takes, such as `String` 
and `int`:
+
+[source,json]
+----
+"bodyTypes": {
+  "expressionOut": { "carriers": [ "unknown" ], "javaTypeOption": "resultType",
+    "description": "A text with functions gives text. A single function, such 
as ${body} or ${header.foo}, gives its value as it is" }
+}
+----
+
 The sides say what the body is with the default options. A side that is not in 
the catalog is not known, and tooling
 should not guess it. The documentation page of a component, data format, 
language or EIP shows them in its _Message
 Body_ section, and `camel catalog doc` prints them. The Java API gives them on 
the model:
@@ -206,8 +224,9 @@ public class FileEndpoint extends GenericFileEndpoint<File> 
{
 
 The build checks that each side belongs to the kind (a consumer-only component 
has no producer sides), that the
 options a side names exist, that a value of an option is one the option can 
have (such as `chat-completion` for the
-`operation` of openai), that `unchanged` is only on the body after a step and 
`any` only on what a step needs, and
-that `from` names a side the body can come from.
+`operation` of openai), that `unchanged` is only on the body after a step and 
`any` only on what a step needs,
+that `from` names a side the body can come from, and that a `javaTypeOption` 
is an option of the body after a step
+that the side does not also depend on.
 The values are read from the code that sets the body, and checked against the 
body types the message history records
 when the routes run.
 
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java
index 50036755e5c5..126131cdc4c6 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java
@@ -1648,7 +1648,8 @@ public final class CatalogDocs {
 
     /**
      * The body types a line per side, as compact as the options are: the 
carriers, the Java type, the format, the
-     * description, the body for other option values, and the options that 
make it not known (CAMEL-24961).
+     * description, the option that names its class, the body for other option 
values, and the options that make it not
+     * known (CAMEL-24961).
      */
     public static JsonObject bodyTypes(Map<String, BodyTypeModel> bodyTypes) {
         JsonObject answer = new JsonObject();
@@ -1662,6 +1663,11 @@ public final class CatalogDocs {
             if (side.getDescription() != null) {
                 line.append(". ").append(side.getDescription());
             }
+            if (side.getJavaTypeOption() != null) {
+                // the option names the class of the body, whatever the other 
options say (CAMEL-25928)
+                line.append(". With ").append(side.getJavaTypeOption())
+                        .append(" set: an object of the class it names, or 
null");
+            }
             if (!side.getByOption().isEmpty()) {
                 List<String> values = new ArrayList<>();
                 for (BodyTypeModel.OptionBodyTypeModel option : 
side.getByOption()) {
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java
index c17649b4cd72..dc2bfbca27da 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java
@@ -158,7 +158,12 @@ class CatalogDocsTest {
         // a language: what its expressions read, and their result
         JsonObject xpath = catalogDoc(Map.of("name", "xpath", "kind", 
"language", "includeOptions", false));
         assertTrue(((JsonObject) 
xpath.get("bodyTypes")).getString("expressionOut")
-                .startsWith("pojo (org.w3c.dom.NodeList). The nodes the 
expression selects. With resultQName=STRING: text"));
+                .startsWith("pojo (org.w3c.dom.NodeList). The nodes the 
expression selects. With resultType set: an object"
+                            + " of the class it names, or null. With 
resultQName=STRING: text"));
+        // CAMEL-25928: the option that names the class of the body
+        JsonObject simple = catalogDoc(Map.of("name", "simple", "kind", 
"language", "includeOptions", false));
+        assertTrue(((JsonObject) 
simple.get("bodyTypes")).getString("expressionOut")
+                .endsWith(". With resultType set: an object of the class it 
names, or null"));
 
         // an EIP: the body after it, the body its steps start with, and the 
side of another model it comes from
         JsonObject split = catalogDoc(Map.of("name", "split", "kind", "eip", 
"includeOptions", false));
@@ -170,6 +175,9 @@ class CatalogDocsTest {
         JsonObject marshal = catalogDoc(Map.of("name", "marshal", "kind", 
"eip", "includeOptions", false));
         assertTrue(((JsonObject) marshal.get("bodyTypes")).getString("eipOut")
                 .startsWith("what its data format marshals to. "));
+        JsonObject convertBodyTo = catalogDoc(Map.of("name", "convertBodyTo", 
"kind", "eip", "includeOptions", false));
+        assertTrue(((JsonObject) 
convertBodyTo.get("bodyTypes")).getString("eipOut")
+                .endsWith(". With type set: an object of the class it names, 
or null"));
 
         // a model that does not declare them, such as the batch settings of 
resequence, has none, rather than a guess
         JsonObject batchConfig = catalogDoc(Map.of("name", "batchConfig", 
"kind", "eip", "includeOptions", false));
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BodyTypeModel.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BodyTypeModel.java
index cc1ee560710b..c6349aada30b 100644
--- 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BodyTypeModel.java
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BodyTypeModel.java
@@ -17,7 +17,9 @@
 package org.apache.camel.tooling.model;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * One side of the body types of a component, data format, language or EIP: 
the body a step needs, or the body it leaves
@@ -58,12 +60,19 @@ public class BodyTypeModel {
     /** The value of {@link #getFrom()} for the body the steps of an EIP end 
with. */
     public static final String FROM_STEPS = "steps";
 
+    /**
+     * The carriers of the classes a type option often names, by name, the 
short names Camel takes as well: java.lang
+     * without the package, and the primitives.
+     */
+    private static final Map<String, String> CARRIERS = carriers();
+
     private List<String> carriers = new ArrayList<>();
     private String javaType;
     private String format;
     private List<String> dependsOn = new ArrayList<>();
     private List<OptionBodyTypeModel> byOption = new ArrayList<>();
     private String from;
+    private String javaTypeOption;
     private String description;
 
     /**
@@ -145,6 +154,85 @@ public class BodyTypeModel {
         this.from = from;
     }
 
+    /**
+     * The option that names the Java type of the body, such as resultType of 
a language: when it is set, and the
+     * options of {@link #getDependsOn()} keep their defaults, the body is of 
the class it names, or null, and the
+     * bodies of {@link #getByOption()} for other options do not hold. The 
carriers say the body when it is not set.
+     */
+    public String getJavaTypeOption() {
+        return javaTypeOption;
+    }
+
+    public void setJavaTypeOption(String javaTypeOption) {
+        this.javaTypeOption = javaTypeOption;
+    }
+
+    /**
+     * The carrier of a body of a Java type, such as a type option names: text 
for String, bytes for byte[], stream,
+     * file, value, map, list (a Collection or an array) and iterator, unknown 
for Object, which can be anything, and
+     * pojo for any other class. The type is a class name, with or without 
generics, or a short name Camel takes, such
+     * as String or int.
+     */
+    public static String carrierOf(String javaType) {
+        if (javaType == null || javaType.isBlank()) {
+            return "unknown";
+        }
+        String name = javaType.trim();
+        int generic = name.indexOf('<');
+        if (generic > 0) {
+            name = name.substring(0, generic).trim();
+        }
+        String answer = CARRIERS.get(name);
+        if (answer != null) {
+            return answer;
+        }
+        if (name.endsWith("[]")) {
+            return "list";
+        }
+        return "pojo";
+    }
+
+    private static Map<String, String> carriers() {
+        Map<String, String> answer = new HashMap<>();
+        for (String name : List.of("String", "java.lang.String", 
"java.lang.CharSequence", "java.lang.StringBuilder")) {
+            answer.put(name, "text");
+        }
+        // java.lang.byte[] is a name Camel accepts for byte[] 
(ObjectHelper.loadSimpleType), as in convertBodyTo
+        for (String name : List.of("byte[]", "java.lang.byte[]")) {
+            answer.put(name, "bytes");
+        }
+        for (String name : List.of("java.io.InputStream", 
"java.io.ByteArrayInputStream", "java.io.Reader",
+                "org.apache.camel.StreamCache")) {
+            answer.put(name, "stream");
+        }
+        for (String name : List.of("java.io.File", "java.nio.file.Path", 
"org.apache.camel.WrappedFile",
+                "org.apache.camel.component.file.GenericFile")) {
+            answer.put(name, "file");
+        }
+        for (String name : List.of("Boolean", "Integer", "Long", "Short", 
"Byte", "Float", "Double", "Character",
+                "Number")) {
+            answer.put(name, "value");
+            answer.put("java.lang." + name, "value");
+        }
+        for (String name : List.of("boolean", "int", "long", "short", "byte", 
"float", "double", "char",
+                "java.math.BigDecimal", "java.math.BigInteger")) {
+            answer.put(name, "value");
+        }
+        for (String name : List.of("java.util.Map", "java.util.HashMap", 
"java.util.LinkedHashMap", "java.util.TreeMap",
+                "java.util.Properties")) {
+            answer.put(name, "map");
+        }
+        for (String name : List.of("java.util.Collection", "java.util.List", 
"java.util.ArrayList",
+                "java.util.LinkedList", "java.util.Set", "java.util.HashSet", 
"java.util.LinkedHashSet",
+                "java.util.TreeSet")) {
+            answer.put(name, "list");
+        }
+        answer.put("java.util.Iterator", "iterator");
+        answer.put("Object", "unknown");
+        answer.put("java.lang.Object", "unknown");
+        return Map.copyOf(answer);
+    }
+
     /**
      * Whether the body is left as it was (for the body after a step).
      */
@@ -167,6 +255,9 @@ public class BodyTypeModel {
         if (from != null) {
             answer = answer.isEmpty() ? "from:" + from : answer + " (from:" + 
from + ")";
         }
+        if (javaTypeOption != null) {
+            answer = answer + " (javaTypeOption:" + javaTypeOption + ")";
+        }
         return answer;
     }
 
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
index e95b39ce3e9e..5e35d04f04a4 100644
--- 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
@@ -728,6 +728,7 @@ public final class JsonMapper {
                 }
             }
             bodyType.setFrom(side.getString("from"));
+            bodyType.setJavaTypeOption(side.getString("javaTypeOption"));
             bodyType.setDescription(side.getString("description"));
             answer.put(entry.getKey(), bodyType);
         }
@@ -749,7 +750,7 @@ public final class JsonMapper {
     /**
      * The body types of a component, data format, language or EIP as the 
catalog has them: an object per side, with the
      * carriers, the Java type, the format, the options it depends on, the 
body for other option values, the side of
-     * another model the body comes from and the description (CAMEL-24961).
+     * another model the body comes from, the option that names its Java type 
and the description (CAMEL-24961).
      */
     public static JsonObject asJsonObjectBodyTypes(Map<String, BodyTypeModel> 
bodyTypes) {
         JsonObject json = new JsonObject();
@@ -778,6 +779,7 @@ public final class JsonMapper {
                 side.put("byOption", byOption);
             }
             side.put("from", bodyType.getFrom());
+            side.put("javaTypeOption", bodyType.getJavaTypeOption());
             side.put("description", bodyType.getDescription());
             side.entrySet().removeIf(e -> e.getValue() == null);
             json.put(entry.getKey(), side);
diff --git 
a/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/JsonMapperTest.java
 
b/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/JsonMapperTest.java
index be2df00e419f..7c15c77e89fc 100644
--- 
a/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/JsonMapperTest.java
+++ 
b/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/JsonMapperTest.java
@@ -196,6 +196,47 @@ class JsonMapperTest {
         assertEquals("unchanged", 
model2.getBodyType(BodyTypeModel.EIP_STEPS).toString());
     }
 
+    @Test
+    void testShouldReadAndWriteJavaTypeOption() {
+        // CAMEL-25928: the option that names the Java type of the body, such 
as resultType of a language
+        LanguageModel model = new LanguageModel();
+        model.setName("simple");
+        BodyTypeModel out = new BodyTypeModel();
+        out.setCarriers(List.of("unknown"));
+        out.setJavaTypeOption("resultType");
+        model.getBodyTypes().put(BodyTypeModel.EXPRESSION_OUT, out);
+
+        String json = JsonMapper.createParameterJsonSchema(model);
+        assertTrue(json.contains("\"javaTypeOption\": \"resultType\""), json);
+        BodyTypeModel out2 = 
JsonMapper.generateLanguageModel(json).getBodyType(BodyTypeModel.EXPRESSION_OUT);
+        assertEquals("resultType", out2.getJavaTypeOption());
+        assertTrue(out2.isUnknown());
+        assertEquals("unknown (javaTypeOption:resultType)", out2.toString());
+    }
+
+    @Test
+    void testCarrierOfJavaType() {
+        // CAMEL-25928: the carrier of the class a type option names, in the 
names Camel takes
+        assertEquals("text", BodyTypeModel.carrierOf("String"));
+        assertEquals("text", BodyTypeModel.carrierOf("java.lang.String"));
+        assertEquals("bytes", BodyTypeModel.carrierOf("byte[]"));
+        assertEquals("bytes", BodyTypeModel.carrierOf("java.lang.byte[]"));
+        assertEquals("stream", BodyTypeModel.carrierOf("java.io.InputStream"));
+        assertEquals("file", BodyTypeModel.carrierOf("java.io.File"));
+        assertEquals("value", BodyTypeModel.carrierOf("int"));
+        assertEquals("value", BodyTypeModel.carrierOf("Integer"));
+        assertEquals("value", BodyTypeModel.carrierOf("java.math.BigDecimal"));
+        assertEquals("map", BodyTypeModel.carrierOf("java.util.Map<String, 
Object>"));
+        assertEquals("list", BodyTypeModel.carrierOf("java.util.List"));
+        assertEquals("list", BodyTypeModel.carrierOf("java.util.Set"));
+        assertEquals("list", BodyTypeModel.carrierOf("String[]"));
+        assertEquals("iterator", 
BodyTypeModel.carrierOf("java.util.Iterator"));
+        assertEquals("pojo", BodyTypeModel.carrierOf("org.w3c.dom.Document"));
+        assertEquals("pojo", BodyTypeModel.carrierOf("com.foo.Order"));
+        assertEquals("unknown", BodyTypeModel.carrierOf("java.lang.Object"));
+        assertEquals("unknown", BodyTypeModel.carrierOf(null));
+    }
+
     @Test
     void testShouldWriteBodyTypesOnlyWhenSet() {
         // CAMEL-24961: the body a step needs and the body it leaves
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/BodyTypesHelper.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/BodyTypesHelper.java
index a5aa6a42fff9..916e91ee29d4 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/BodyTypesHelper.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/BodyTypesHelper.java
@@ -95,7 +95,8 @@ final class BodyTypesHelper {
             BodyType bodyType = entry.getValue();
             if (bodyType.value().length == 0 && bodyType.from().isEmpty()) {
                 if (!bodyType.javaType().isEmpty() || 
!bodyType.format().isEmpty() || bodyType.dependsOn().length > 0
-                        || bodyType.byOption().length > 0 || 
!bodyType.description().isEmpty()) {
+                        || bodyType.byOption().length > 0 || 
!bodyType.javaTypeOption().isEmpty()
+                        || !bodyType.description().isEmpty()) {
                     throw new IllegalArgumentException(
                             owner.getName() + ": the @BodyTypes " + side + " 
has no carriers, but other attributes");
                 }
@@ -119,6 +120,9 @@ final class BodyTypesHelper {
                 checkValue(owner, side, when, options.get(when.option()));
                 check(owner, side + " " + when.option() + "=" + when.value(), 
when.carriers());
             }
+            if (!bodyType.javaTypeOption().isEmpty()) {
+                checkJavaTypeOption(owner, side, bodyType, options);
+            }
             model.getBodyTypes().put(side, asModel(bodyType));
         }
     }
@@ -141,6 +145,32 @@ final class BodyTypesHelper {
         }
     }
 
+    /**
+     * The option that names the Java type says the body after a step when it 
is set, whatever other options say: the
+     * class of what a step needs is not a choice of the step, and an option 
that is also one the body depends on, or
+     * has bodies for its values, would say two things.
+     */
+    private static void checkJavaTypeOption(
+            Class<?> owner, String side, BodyType bodyType, Map<String, 
BaseOptionModel> options) {
+        String option = bodyType.javaTypeOption();
+        checkOption(owner, side, option, options);
+        if (IN.contains(side)) {
+            throw new IllegalArgumentException(
+                    owner.getName() + ": the @BodyTypes " + side + " is what a 
step needs, which has no javaTypeOption");
+        }
+        if (!bodyType.from().isEmpty()) {
+            throw new IllegalArgumentException(
+                    owner.getName() + ": the @BodyTypes " + side + " is from " 
+ bodyType.from()
+                                               + ", so it has no 
javaTypeOption of its own");
+        }
+        if (Arrays.asList(bodyType.dependsOn()).contains(option)
+                || Arrays.stream(bodyType.byOption()).anyMatch(w -> 
w.option().equals(option))) {
+            throw new IllegalArgumentException(
+                    owner.getName() + ": the @BodyTypes " + side + " has the 
javaTypeOption " + option
+                                               + ", which must not also be in 
dependsOn or byOption");
+        }
+    }
+
     private static Set<String> allowedSides(BaseModel<?> model) {
         return switch (model.getKind()) {
             case component -> {
@@ -252,6 +282,7 @@ final class BodyTypesHelper {
             model.getByOption().add(option);
         }
         model.setFrom(emptyAsNull(bodyType.from()));
+        model.setJavaTypeOption(emptyAsNull(bodyType.javaTypeOption()));
         model.setDescription(emptyAsNull(bodyType.description()));
         return model;
     }
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/BodyTypesHelperJavaTypeOptionTest.java
 
b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/BodyTypesHelperJavaTypeOptionTest.java
new file mode 100644
index 000000000000..e96afeb8b11d
--- /dev/null
+++ 
b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/BodyTypesHelperJavaTypeOptionTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.maven.packaging;
+
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
+import org.apache.camel.tooling.model.BaseModel;
+import org.apache.camel.tooling.model.BodyTypeModel;
+import org.apache.camel.tooling.model.EipModel;
+import org.apache.camel.tooling.model.LanguageModel;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The option that names the Java type of the body, such as resultType of a 
language (CAMEL-25928).
+ */
+class BodyTypesHelperJavaTypeOptionTest {
+
+    @BodyTypes(expressionIn = @BodyType(Carrier.ANY),
+               expressionOut = @BodyType(value = Carrier.UNKNOWN, 
javaTypeOption = "resultType"))
+    static class SomeLanguage {
+    }
+
+    @BodyTypes(expressionIn = @BodyType(value = Carrier.ANY, javaTypeOption = 
"resultType"))
+    static class OnWhatTheStepNeeds {
+    }
+
+    @BodyTypes(expressionOut = @BodyType(value = Carrier.UNKNOWN, 
javaTypeOption = "outputType"))
+    static class NotAnOption {
+    }
+
+    @BodyTypes(expressionOut = @BodyType(value = Carrier.TEXT, dependsOn = 
"resultType", javaTypeOption = "resultType"))
+    static class AlsoInDependsOn {
+    }
+
+    @BodyTypes(expressionOut = @BodyType(value = Carrier.TEXT, javaTypeOption 
= "resultType",
+                                         byOption = @BodyType.When(option = 
"resultType", value = "String",
+                                                                   carriers = 
Carrier.TEXT)))
+    static class AlsoInByOption {
+    }
+
+    @BodyTypes(eipOut = @BodyType(from = "expressionOut", javaTypeOption = 
"type"))
+    static class WithFrom {
+    }
+
+    @Test
+    void javaTypeOption() {
+        LanguageModel model = language();
+        add(model, SomeLanguage.class);
+
+        BodyTypeModel out = model.getBodyType(BodyTypeModel.EXPRESSION_OUT);
+        assertEquals("resultType", out.getJavaTypeOption());
+        assertTrue(out.isUnknown());
+        
assertNull(model.getBodyType(BodyTypeModel.EXPRESSION_IN).getJavaTypeOption());
+    }
+
+    @Test
+    void onlyForTheBodyAfterAStep() {
+        assertThrows(IllegalArgumentException.class, () -> add(language(), 
OnWhatTheStepNeeds.class));
+    }
+
+    @Test
+    void anOptionOfTheModel() {
+        assertThrows(IllegalArgumentException.class, () -> add(language(), 
NotAnOption.class));
+    }
+
+    @Test
+    void oneMeaningPerOption() {
+        assertThrows(IllegalArgumentException.class, () -> add(language(), 
AlsoInDependsOn.class));
+        assertThrows(IllegalArgumentException.class, () -> add(language(), 
AlsoInByOption.class));
+    }
+
+    @Test
+    void notWithFrom() {
+        EipModel model = new EipModel();
+        model.setName("someEip");
+        EipModel.EipOptionModel option = new EipModel.EipOptionModel();
+        option.setName("type");
+        option.setType("string");
+        model.addOption(option);
+        assertThrows(IllegalArgumentException.class, () -> add(model, 
WithFrom.class));
+    }
+
+    private static LanguageModel language() {
+        LanguageModel model = new LanguageModel();
+        model.setName("someLanguage");
+        LanguageModel.LanguageOptionModel option = new 
LanguageModel.LanguageOptionModel();
+        option.setName("resultType");
+        option.setType("string");
+        model.addOption(option);
+        return model;
+    }
+
+    private static void add(BaseModel<?> model, Class<?> owner) {
+        BodyTypesHelper.addBodyTypes(model, 
owner.getAnnotation(BodyTypes.class), owner);
+    }
+}
diff --git 
a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/BodyType.java 
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/BodyType.java
index 5530d2317eb2..7f18b4d3460c 100644
--- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/BodyType.java
+++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/BodyType.java
@@ -73,6 +73,17 @@ public @interface BodyType {
      */
     String from() default "";
 
+    /**
+     * The option that names the Java type of the body, such as {@code 
resultType} of a language, whose result is
+     * converted to the class the option names. When the option is set, and 
the options in {@link #dependsOn()} keep
+     * their default values, the body is of that class, or null when it does 
not convert; the bodies {@link #byOption()}
+     * gives for other options do not hold then. The carriers say the body 
when it is not set. The carrier follows the
+     * class: String is text, byte[] bytes, an InputStream or a Reader a 
stream, a File or a Path a file, a number, a
+     * boolean or a character a value, a Map map, a List, a Set, another 
Collection or an array list, an Iterator
+     * iterator, Object unknown, and any other class pojo.
+     */
+    String javaTypeOption() default "";
+
     /**
      * What to know about the body, in a sentence for the documentation and 
the tools.
      */

Reply via email to