Results 1 to 9 of 9

Thread: sendMessage handles String but not Object

  1. #1

    Question handleMessage handles String but not Object

    Hi,

    I am very impressed with Spring-AMQP...thank you for the great work!!!

    The build I'm using is the 12/27/10 snapshot.

    I've run into a small problem. Sending text as a message works, but sending an object does not.

    When I send a message using:

    Code:
    getRabbitTemplate().convertAndSend(routingKey, "text string");
    handleMessage(String text) in my POJO works fine

    However, when I change the convertAndSend and the POJO signature to an object:

    Code:
    getRabbitTemplate().convertAndSend(routingKey, myObject);
    
    public void handleMessage(MyObject myObject)
    I get this error:

    SimpleMessageListenerContainer - Execution of Rabbit message listener failed, and no ErrorHandler has been set. <org.springframework.amqp.rabbit.listener.adapter. ListenerExecutionFailedException: Failed to invoke target method 'handleMessage' with argument type = [class [B], value = [{[B@7ab05cd7}]>org.springframework.amqp.rabbit.listener.adapter. ListenerExecutionFailedException: Failed to invoke target method 'handleMessage' with argument type = [class [B], value = [{[B@7ab05cd7}]

    Please help with my newb question...thanks!!!
    Last edited by Slidewayz; Dec 31st, 2010 at 02:34 AM.

  2. #2
    Join Date
    Jun 2005
    Posts
    4,230

    Default

    Thanks for the feedback.

    Is MyObject Serializable? I think the default conversion falls back to Object.toString() if it can't serialize. If you need more control you can add a MessageConverter to your producer and consumer.

  3. #3

    Default

    Quote Originally Posted by Dave Syer View Post
    Thanks for the feedback.

    Is MyObject Serializable? I think the default conversion falls back to Object.toString() if it can't serialize. If you need more control you can add a MessageConverter to your producer and consumer.
    I subclassed MyObject to make it Serializable, but still can't get my POJO to accept it as MyObject. I have my RabbitTemplate set to use the JSON converter like the Stock example.

    The Spring-AMQP Stock example appears to be passing Quote w/o it being serialized (RabbitMarketDataGateway, line 69)?

    The Stock example's Client Handler handleMessage (line 47) has Quote as its signature.

    I am essentially trying to do the same thing and AFAIK my code is the same since I based it on the Stock example.

    Please let me know what I am missing.

    Also, is there an example of how to implement MessageConverter? I don't know what MessageProperties to set/pass in.

    Thanks again !!!
    Last edited by Slidewayz; Dec 31st, 2010 at 03:40 AM.

  4. #4
    Join Date
    Jun 2005
    Posts
    4,230

    Default

    If you are using the JsonMessageConverter you don't need to implement Serializable, but your POJO and all its properties have to be convertible to JSON. I can see from your error message now that it is a JSON String, however it's not MyObject that is broken, but one of its properties of type B. Does that make sense? I'm not sure why the B is not convertible, but maybe we can work it out if you paste the source code.

  5. #5

    Default

    Thank you once again, Dave.

    The object I'm passing in is a value object. It has data types of string, int, boolean, date, and float. Along with that it has setters and getters and also hibernate stuff.

    ...I guess that is way too confusing for a json conversion!

    I will create a simplified value object with only string & int properties and try that.

  6. #6

    Default

    I've created a very simple value object that contains 1 string and 2 ints.

    In the Spring-AMQP Stock example, I do not see any config of the JSON converter that I have not included (my messageListenerAdapter bean is identical).

    When I pass this as an argument to convertAndSend, I still get the following error from Jackson. Why would I need to 'add/enable type information' when the Stock example does not? I am using jackson-all-1.6.4.jar and the 12/27 SNAPSHOT build of Spring-AMQP.

    Code:
    WARN] SimpleMessageListenerContainer - Execution of Rabbit message listener failed, and no ErrorHandler has been set. <org.springframework.amqp.support.converter.MessageConversionException: Failed to convert Message content>org.springframework.amqp.support.converter.MessageConversionException: Failed to convert Message content
    	at org.springframework.amqp.support.converter.JsonMessageConverter.fromMessage(JsonMessageConverter.java:118)
    	at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.extractMessage(MessageListenerAdapter.java:384)
    	at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:332)
    	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:280)
    	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:243)
    	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:222)
    	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:192)
    	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.receiveAndExecute(SimpleMessageListenerContainer.java:388)
    	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:307)
    	at java.lang.Thread.run(Thread.java:680)
    Caused by: org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class rabbit.gateway.MyDataGateway$MyMockObject]: can not instantiate from JSON object (need to add/enable type information?)
     at [Source: java.io.StringReader@54a50a00; line: 1, column: 2]
    	at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:160)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:478)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
    	at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1980)
    	at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1271)
    	at org.springframework.amqp.support.converter.JsonMessageConverter.convertBytesToObject(JsonMessageConverter.java:137)
    	at org.springframework.amqp.support.converter.JsonMessageConverter.fromMessage(JsonMessageConverter.java:109)
    	... 9 more

  7. #7
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    I would expect that if your object has no default constructor. Is that the case?

  8. #8

    Default

    Quote Originally Posted by Mark Fisher View Post
    I would expect that if your object has no default constructor. Is that the case?
    Funny you should ask that...I just added a public default empty constructor and a public constructor that sets all the properties from passed-in parms.

    I still get the same error.

  9. #9

    Default

    OK. I got it working by removing the MockObject that extends my class.

    I think I now understand why the code in the AMQP-Stock example works (RabbitMarketDataGateway). Your MockStock is not what is sent in the message. I was sending my MockObject, so jackson didn't know how to type it.

    Would I solve this problem by adding a default constructor for my MockObject inner class ?

    Thank you all for your help !!!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •