This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch CAMEL-26567
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/CAMEL-26567 by this push:
new 1c45a20bef99 CAMEL-26567: camel-jms / camel-sjms - text that is not a
String in a Map body goes in the MapMessage as a String
1c45a20bef99 is described below
commit 1c45a20bef99cabc6fbcbe2477c5f331b5b38bf5
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Nov 4 10:48:40 2026 +0100
CAMEL-26567: camel-jms / camel-sjms - text that is not a String in a Map
body goes in the MapMessage as a String
A MapMessage takes only primitive wrappers, String and byte[], so a Map
with a StringBuilder or a Groovy GString value failed with a
MessageFormatException.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../org/apache/camel/component/jms/JmsBinding.java | 5 +++-
.../component/jms/JmsCharSequenceBodyTest.java | 27 ++++++++++++++++++++++
.../camel/component/sjms/jms/JmsBinding.java | 5 +++-
.../sjms/producer/CharSequenceBodyTest.java | 24 +++++++++++++++++++
4 files changed, 59 insertions(+), 2 deletions(-)
diff --git
a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsBinding.java
b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsBinding.java
index f4ebe88b999f..df0b4d06ecd2 100644
---
a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsBinding.java
+++
b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsBinding.java
@@ -853,7 +853,10 @@ public class JmsBinding {
for (Entry<?, ?> entry : map.entrySet()) {
String keyString = CamelContextHelper.convertTo(context,
String.class, entry.getKey());
if (keyString != null) {
- message.setObject(keyString, entry.getValue());
+ Object value = entry.getValue();
+ // JMS takes only primitive wrappers, String and byte[] in a
MapMessage, so text such as a
+ // StringBuilder or a Groovy GString goes in as a String
+ message.setObject(keyString, value instanceof CharSequence cs
? cs.toString() : value);
}
}
}
diff --git
a/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsCharSequenceBodyTest.java
b/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsCharSequenceBodyTest.java
index c2da066fc170..a618bcd4d7cb 100644
---
a/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsCharSequenceBodyTest.java
+++
b/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsCharSequenceBodyTest.java
@@ -16,6 +16,10 @@
*/
package org.apache.camel.component.jms;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import jakarta.jms.MapMessage;
import jakarta.jms.TextMessage;
import com.example.external.ExternalText;
@@ -64,6 +68,27 @@ public class JmsCharSequenceBodyTest extends AbstractJMSTest
{
assertInstanceOf(TextMessage.class, in.getJmsMessage());
}
+ @Test
+ public void testTextInAMapIsSentAsString() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:map");
+ mock.expectedMessageCount(1);
+
+ // a Map with text that is not a String, as a Groovy script that
returns [status: "not enough ${sku}"]
+ Map<String, Object> body = new LinkedHashMap<>();
+ body.put("status", new ExternalText("not enough CAMEL-CAP"));
+ body.put("note", new StringBuilder("back order"));
+ body.put("count", 3);
+ template.sendBody("jms:queue:JmsCharSequenceBodyTest.map", body);
+
+ MockEndpoint.assertIsSatisfied(context);
+ JmsMessage in =
mock.getReceivedExchanges().get(0).getIn(JmsMessage.class);
+ assertInstanceOf(MapMessage.class, in.getJmsMessage());
+ Map<?, ?> received = in.getBody(Map.class);
+ assertEquals("not enough CAMEL-CAP", received.get("status"));
+ assertEquals("back order", received.get("note"));
+ assertEquals(3, received.get("count"));
+ }
+
@Test
public void testTextReply() {
Object reply =
template.requestBody("jms:queue:JmsCharSequenceBodyTest.reply?requestTimeout=5000",
"CAMEL-CAP");
@@ -85,6 +110,8 @@ public class JmsCharSequenceBodyTest extends AbstractJMSTest
{
public void configure() {
from("jms:queue:JmsCharSequenceBodyTest").to("mock:result");
+ from("jms:queue:JmsCharSequenceBodyTest.map").to("mock:map");
+
// a reply that is text but not a String, as a route that sets
the body with a Groovy GString
from("jms:queue:JmsCharSequenceBodyTest.reply")
.process(e -> e.getMessage().setBody(new
ExternalText("not enough " + e.getMessage().getBody())));
diff --git
a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/jms/JmsBinding.java
b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/jms/JmsBinding.java
index cfc46b6e1036..bea673b2193d 100644
---
a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/jms/JmsBinding.java
+++
b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/jms/JmsBinding.java
@@ -632,7 +632,10 @@ public class JmsBinding {
for (Map.Entry<?, ?> entry : map.entrySet()) {
String keyString = CamelContextHelper.convertTo(context,
String.class, entry.getKey());
if (keyString != null) {
- message.setObject(keyString, entry.getValue());
+ Object value = entry.getValue();
+ // JMS takes only primitive wrappers, String and byte[] in a
MapMessage, so text such as a
+ // StringBuilder or a Groovy GString goes in as a String
+ message.setObject(keyString, value instanceof CharSequence cs
? cs.toString() : value);
}
}
}
diff --git
a/components/camel-sjms/src/test/java/org/apache/camel/component/sjms/producer/CharSequenceBodyTest.java
b/components/camel-sjms/src/test/java/org/apache/camel/component/sjms/producer/CharSequenceBodyTest.java
index f70eb7c7eace..f1455e4110da 100644
---
a/components/camel-sjms/src/test/java/org/apache/camel/component/sjms/producer/CharSequenceBodyTest.java
+++
b/components/camel-sjms/src/test/java/org/apache/camel/component/sjms/producer/CharSequenceBodyTest.java
@@ -16,6 +16,10 @@
*/
package org.apache.camel.component.sjms.producer;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import jakarta.jms.MapMessage;
import jakarta.jms.Message;
import jakarta.jms.MessageConsumer;
import jakarta.jms.TextMessage;
@@ -36,6 +40,7 @@ public class CharSequenceBodyTest extends JmsTestSupport {
private static final String TEST_DESTINATION_NAME =
"test.foo.CharSequenceBodyTest";
private static final String TEST_OTHER_DESTINATION_NAME =
"test.other.CharSequenceBodyTest";
+ private static final String TEST_MAP_DESTINATION_NAME =
"test.map.CharSequenceBodyTest";
private static final String TEST_REPLY_DESTINATION_NAME =
"test.reply.CharSequenceBodyTest";
@Override
@@ -68,6 +73,25 @@ public class CharSequenceBodyTest extends JmsTestSupport {
mc.close();
}
+ @Test
+ public void testTextInAMapIsSentAsString() throws Exception {
+ MessageConsumer mc = createQueueConsumer(TEST_MAP_DESTINATION_NAME);
+
+ // a Map with text that is not a String, as a Groovy script that
returns [status: "not enough ${sku}"]
+ Map<String, Object> body = new LinkedHashMap<>();
+ body.put("status", new ExternalText("not enough CAMEL-CAP"));
+ body.put("note", new StringBuilder("back order"));
+ body.put("count", 3);
+ template.sendBody("sjms:queue:" + TEST_MAP_DESTINATION_NAME, body);
+
+ Message message = mc.receive(5000);
+ MapMessage map = assertInstanceOf(MapMessage.class, message);
+ assertEquals("not enough CAMEL-CAP", map.getObject("status"));
+ assertEquals("back order", map.getObject("note"));
+ assertEquals(3, map.getObject("count"));
+ mc.close();
+ }
+
@Test
public void testTextReply() {
Object reply = template.requestBody("sjms:queue:" +
TEST_REPLY_DESTINATION_NAME + "?requestTimeout=5000", "CAMEL-CAP");