skyscreamer / nevado

A JMS driver for Amazon SQS.
http://nevado.skyscreamer.org/
Apache License 2.0
51 stars 48 forks source link

Caucho/Hessian Serialization issues using Nevado as JMS provider for Ehcache JMS replication #81

Open bitsofinfo opened 10 years ago

bitsofinfo commented 10 years ago

@see https://github.com/skyscreamer/nevado/pull/82 for a proposed fix @see post for background https://bitsofinfo.wordpress.com/2014/04/21/ehcache-replicated-caching-with-jms-aws-sqs-sns-nevado/ @see https://github.com/bitsofinfo/ehcache-jms-wan-replicator for more context of how this might be utilized

I'm experimenting w/ using Nevado as the JMS provider w/ Ehcache replicated caching. @see http://ehcache.org/documentation/replication/jms-replicated-caching

I wrote a custom NevadoJMSCacheManagerPeerProviderFactory that sets up the needed topic/queues for Ehcache and it all appears to work as expected. I.E. Spin up 3 JVMs w/ test cache configured to use this. I do a cache PUT operation in one JVM and the other two instances receive the Ehcache replicated cache event as expected all facilitated through Nevado.

However there is one issue.

a) Ehcache is sending a JMSEventMessage @see http://svn.terracotta.org/svn/ehcache/trunk/jmsreplication/src/main/java/net/sf/ehcache/distribution/jms/JMSEventMessage.java

b) NevadoTopicSession.createObjectMessage is passed this JMSEventMessage instance

c) A key field in JMSEventMessage (defined in its parent LegacyEventMessage) is a transient flagged SoftReference to an Ehcache Element (which is where the actual cached data to be replicated is stored). http://grepcode.com/file/repo1.maven.org/maven2/net.sf.ehcache/ehcache-core/2.5.2/net/sf/ehcache/distribution/LegacyEventMessage.java

d) Due to this field being declared transient the Hessian2Output.writeObject routine that uses UnsafeSerializer, this field is discarded as the UnsafeSerializer ignores transient fields. The result of this is that the message is sent, serialized as expected but it is missing its Element field. So the receiving consumers (other ehcache instances) end up w/ null pointer exceptions because this field does not exist (was not serialized and included in the message)

e) Now this works w/ other JMS providers, particularly I looked at ActiveMQ. The reason it works in those is because they use ObjectOutputStream for object serialization, which provides a facility to permit transient field serialization through the "readObject", "writeObject" special serialization methods that classes can optionally declare (as LegacyEventMessage does described in C above). LegacyEventMessage implements these 2 methods to deal w/ the Element field (marked transient) to ensure its is included in the resulting serialized ObjectOutputStream. @see http://grepcode.com/file/repo1.maven.org/maven2/org.apache.activemq/activemq-core/4.1.2/org/apache/activemq/command/ActiveMQObjectMessage.java (the storeContent() method)

f) Anyways, I'm not sure why Nevado uses the Caucho Hessian library for object serialization or if this is something that can be completely worked around or fixed. Possibly this would just help someone else who comes along who is trying to use this library for this purpose.