Conversely, in some cases, you might dramatically improve performance and keep your
code simple by using separate destinations instead of using selectors. In the example, using
separate queues and MDBs for shipping requests and cancellation orders could make mes-
sage delivery much faster. In this case, the client would have to send each request type to
the appropriate queue.
Choose message types carefully . The choice of message type isn't always as obvious as
it seems. For example, it's a compelling idea to use XML strings for messaging. Among
other things, this tends to promote loose coupling between systems. In the example,
Turtle's server would know about the format of the XML messages and not the Ac-
tionBazaarShippingRequest object itself.
The problem is that XML tends to bloat the size of the message, significantly degrading
MOM performance. In certain circumstances, it might even be the right choice to use bin-
ary streams in the message payload, which puts the least amount of demand on MOM pro-
cessing as well as memory consumption.
Be wary of poisoned messages . Imagine that a message is handed to you that your MDB
wasn't able to consume. Using the example, let's assume that you receive a message that's
not an ObjectMessage . As you can see from this code snippet, if this happens, the cast
in onMessage will throw a java.lang.ClassCastException :
Because onMessage won't complete normally, the container will be forced to roll back
the transaction and put the message back on the queue instead of acknowledging it. The
problem is, because you're still listening on the queue, the same message will be delivered
to you again and you'll be stuck in the accept/die loop indefinitely! Messages that cause
this all-too-common scenario are called poisoned messages .