|Rollback in transaction causes BlazeDS 3.x to invoke ClassDescriptor.getInheritancePolicy() [message #546700]
||Tue, 13 July 2010 16:10
| Daniel Shaw
Registered: July 2010
We have been dealing with this bug for a while and really took a lot of time and a second set of eyes to figure out what was happening here. |
We have a web based system deployed on Weblogic which uses Spring Framework to manage our business tier, and Flex for our web clients. We provide our service object layer directly to Flex clients through AMF remote object serialization and usually let the default exception handling in Spring do its thing.
When invoking a remote object through BlazeDS which starts and subsquently rolls back a transaction, BlazeDS attempts to acquire as much information about the Exception Chain as possible and then serializes it to the Flash client. In doing so, it gets an instance/ or instances of ClassDescriptor (on the object that caused the rollback). It then attempts to use JavaBeans type semantics on the ClassDescriptor invoking getInheritancePolicy(), without using the hasInheritance() descriptor check. After this happens, the entire app tier becomes unusable as the entity/entities ClassDescriptors now have an unusable InheritancePolicy object for non inheritance entities.
This can be quite a maddening experience, especially in production, as in our experience, one rollback causes all other clients using our system to be locked out until we restart Weblogic.
We have looked all over the Internet to see if anyone else has experienced this issue, and have found nothing so far. We hope this post can help others.
You can get around the problem by changing the amf channel definition in the web app's services-config.xml by adding a
property to the properties section.
A subsequent rollback here will not cause the methods inside ClassDescriptor to be called and the server side of the system will remain stable. However, you will encounter another bug within BlazeDS: Infinite Recursion. We are attempting to submit a patch for this as well, but the client will not die because of it. It will just never receive the fault message.
Another solution is to ensure that any service method exported as a remote object invocation has a try-catch block that throws a different exception that doesn't include the exception hierarchy in the new exception. This isn't an easy option for us, since we would have to rewrite quite a bit of code.
We question the wisdom in having ClassDescriptor's getInheritancePolicy() initialize an InheritancePolicy if none exists, and also having developers make sure to call hasInheritance() or other variant before invoking getInheritancePolicy(). Is there not a better way? At least make it protected so it can't get called through JavaBeans introspection?
Powered by FUDForum
. Page generated in 0.10383 seconds