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.

Reply via email to