7

I am using Java EE JMS Queue. I am sending objects into the queue and then receive them with a MDB. When reading the message body (with getBody()) into an object I get the following exception:

javax.jms.MessageFormatException: Body not assignable to class ...

Is there any way to get a more descriptive error out of this that would tell why exactly it is not assignable? I also tried to go into debug mode and see what kind of Message object arrives into the MDB but it is serialized as far as I can see so it's not really useful.

Object type is properly recognised in debugger before it is sent to the queue.

Additiona info: if I create an empty object manually and send it, it is properly recognised. The production object comes from a REST endpoint and contains a lot of properties and gets transformed a bunch of times in the process. Some piece of data must be preventing the assignment but debugging each property step by step would be a pain and only as a last resort.

Object is confirmed serializable per answer in how to test in Java that a class implements Serializable correctly (not just is an instance of Serializable)

Object is sent as: jmsContext.createProducer().send(queue, object);

I managed to narrow it down by setting all properties to null and then commenting that out one by one until it worked. It turns out a Duration type property was improperly? initialized which caused the problem. And in another case it was XMLGregorianCalendar property that caused it. Still, this is a very hacky way of debugging and I still don't actually know why exactly the assignment fails, I just know which property causes it.

For the time being I ended up passing entity IDs into the queue instead of full objects and I retreive them from database by the ID instead.

Pastebin of full stacktrace: http://pastebin.com/vWvhDTcr

Community
  • 1
  • 1
cen
  • 2,873
  • 3
  • 31
  • 56
  • 1
    Does the MDB reading the message have access to the class file of the object it's trying to read? – hugh Sep 17 '15 at 07:55
  • The class is imported, Eclipse does not report any warnings or errors about it so I am assuming yes. – cen Sep 17 '15 at 07:57
  • 1
    It's possible to view an example of the sender and the MDB? – Dubas Oct 07 '15 at 10:27
  • 1
    The object is serialized but, The MQ server is capable to handle the raw data provided. Are you sending the byte[] result as a BytesMessage? (http://docs.oracle.com/javaee/6/api/javax/jms/BytesMessage.html) – Dubas Oct 07 '15 at 10:33
  • Added some more info in an edit. I am not sending it as a BytesMessage. – cen Oct 07 '15 at 20:10
  • Can you provide the complete stack trace including any "caused by ..." parts? – Steve C Oct 08 '15 at 00:08

2 Answers2

1

A good design(if you have control over it now, meaning its a new app not already in production) may be to use json payloads, that way you can see the payload as text at any time, the json deserializers like jackson spit out better exceptions.

Gregorian Calendars are painful for xml serialization atleast from my experience, you are better off using something like joda time.

Mahesh
  • 1,583
  • 13
  • 18
  • Probably a good advice, the only problem is that I'd be re-serializing the object to json because we use calling EJB as SOAP webservice which is called by the rest endpoint. So Rest->deserialize->Ejb->serialize->Jms. it'd work but seems like conflict with our current design. – cen Oct 14 '15 at 13:57
0

The whole graph of objects you put in the Queue must be imported and accessible in the MDB. Including standard format like java.util.GregorianCalendar

Antoine Claval
  • 4,923
  • 7
  • 40
  • 68
  • Agree with Antoine also, you probably have a nested Class not found exception somewhere. Can you paste the whole stack trace(with all the nested exceptions), that will be helpful. – Mahesh Oct 13 '15 at 03:57
  • The class I am assigning to is imported so by definition all member classes should be imported too, right? – cen Oct 13 '15 at 08:56
  • No, all member class will not be imported automatically. – Antoine Claval Oct 13 '15 at 17:04
  • @Mahesh is giving nice advice : having a payloads ( text version ) of your object graph would allow you to unit test and debug more easily. – Antoine Claval Oct 13 '15 at 17:05
  • The EJB that sends the object and Mdb are in the same EAR module so they should both have the same dependencies imported and available. Unless you mean to explicitly ```import``` them in the ejb class but that doesn't make any sense to me. – cen Oct 14 '15 at 14:00