Hi All, sorry for spamming around SJMS component but I'm having issues with it :-( Now I'm getting NPE when I'm trying to send a message with content created using POJO created with JAXB.
I think that it is a bug in the JmsMessageHelper with results in Null Pointer exceptions. It looks like the function: JmsMessageHelper.discoverMessageTypeFromPayload(payload) can return type of JmsMessageType.Message but this type is not supported by the caller createMessage method. JmsMessageType.Message is returned in two cases when body payload is either "null" or unknown type. Extract from the function: (...) private static Message createMessage(Session session, Object payload, Map<String, Object> messageHeaders, KeyFormatStrategy keyFormatStrategy, TypeConverter typeConverter) throws Exception { Message answer = null; JmsMessageType messageType = JmsMessageHelper.discoverMessageTypeFromPayload(payload); try { switch (messageType) { case Bytes: (...) case Map: (...) case Object: (...) case Text: (...) case Stream: (...) //////////////////////////////////////// /////////////// SK: WHERE IS case Message: ? //////////////////////////////////////// default: break; // ? Unknown type is silently ignored. Wouldn't it be better to default to Object type? } } catch (Exception e) { LOGGER.error("Error creating a message of type: {}", messageType, e); throw e; } if (messageHeaders != null && !messageHeaders.isEmpty()) { answer = JmsMessageHelper.setJmsMessageHeaders(answer, messageHeaders, keyFormatStrategy); } return answer; } (...) This problem can be reproduced with this unit test (tested on 2.14.0): @Test public void testCreationOfUnknownPayloadType() throws Exception { Connection conn = connectionFactory.createConnection(); Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); Map<String, Object> sampleMap = new HashMap<String, Object>(); sampleMap.put("test", 5L); Message msg = JmsMessageHelper.createMessage(session, null, sampleMap, null); session.close(); conn.close(); } I guess it would be enough to do this in order to fix the problem (Patch works with 2.14.x and 2.15.0): $ diff -c JmsMessageHelper.java.org JmsMessageHelper.java *** JmsMessageHelper.java.org 2015-03-07 04:20:32.000000000 +0100 --- JmsMessageHelper.java 2015-03-13 12:00:17.791081500 +0100 *************** *** 195,200 **** --- 195,210 ---- } answer = streamMessage; break; + case Message: + if (payload == null) { + // Create empty message + answer = session.createMessage(); + } else { + // Throw exception as there is a playload but it is not supported by JMS + throw new JMSException("Unsupported message payload type"); + } + break; default: break; } Unit test for Camel 2.14.x (Unfortunately in Camel 2.15.0 it got more complex to test createMessage function) because of need of SjmsEndpoint as parameter: WARNING!: This test will fail on 2.15.0 !!! as API has changed. I guess I could port it to newer version but first please confirm that fix is "valid". package org.apache.camel.component.sjms.bugfixes; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import org.apache.camel.component.sjms.jms.*; import javax.jms.Connection; import javax.jms.Message; import javax.jms.Session; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.camel.test.junit4.TestSupport; import org.junit.After; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import org.junit.Before; import org.junit.Test; public class JmsMessageHelperNpe { private ActiveMQConnectionFactory connectionFactory; @Before public void setup() { connectionFactory = new ActiveMQConnectionFactory("vm://broker?broker.persistent=false&broker.useJmx=false"); } @After public void teardown() { connectionFactory = null; } @Test public void testCreationOfNullpayloadMessage() throws Exception { Connection connection = connectionFactory.createConnection(); assertNotNull(connection); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); assertNotNull(session); Map<String, Object> sampleMap = new HashMap<String, Object>(); sampleMap.put("test", 5L); Object nullObject = null; Message msg = JmsMessageHelper.createMessage(session, nullObject, sampleMap, null); assertNotNull(msg); session.close(); connection.close(); } @Test public void testCreationOfUnknownPayloadMessage() throws Exception { Connection connection = connectionFactory.createConnection(); assertNotNull(connection); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); assertNotNull(session); Map<String, Object> sampleMap = new HashMap<String, Object>(); sampleMap.put("test", 5L); Object helloWorld = new Object() { private Integer someValue = 5; }; try { Message msg = JmsMessageHelper.createMessage(session, helloWorld, sampleMap, null); fail("Exception is expected"); } catch (Exception e) { TestSupport.assertStringContains(e.getMessage(), "Unsupported message payload type"); } session.close(); connection.close(); } } Thanks & Kind regards, Stan -- View this message in context: http://camel.465427.n5.nabble.com/Camel-SJMS-Null-pointer-exception-when-sending-a-message-proposed-patch-tp5764093.html Sent from the Camel - Users mailing list archive at Nabble.com.