How to handle NotSerializableException for EJB's with @Remote interfaces in EAP
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- Java Enterprise Beans (EJB)
Issue
- If I use EJB's implementing a Remote interface why there is a need to have all parameters, return objects and declared Exceptions marked as Serializable?
- In our application, we have EJB calls within the same EAR deployment. Except the data exchanged by EJB are often not marked Serializable, so we use the option
on the EJB container within the EAP configuration. But the invocation fail for some reason to some methods or if an Exception is thrown. What is the reason for this? - We migrate from WebSphere to EAP and found issues if we enabled
<in-vm-remote-interface-invocation pass-by-value="false">to have an equivalent for such option in WebSphere. For EAP 7.1 we don't see an issue but there are failures if we use EAP 7.2, what is the reason?
Resolution
If the EJB implements a Remote-interface all parameters, return-values and Exceptions which are part of this remote-interface it is indespensable to mark these obects as Serializable, this includes all embedded objects which are not marked as static or transient
This is part of the EJB Bean contract.
The configuration <in-vm-remote-interface-invocation pass-by-value="false"> will only work if the caller and callee are within the same JVM.
But consider that enable this for an EJB which has an interface marked with @Remote is a potential risk as it will break the contract of decoupling. If enabled the called EJB is able to change mutable parameter and the caller is able to change the returned object if mutable.
This might cause non deterministic random failure which are hard to find.
The pass-by-value=false or pass-by-reference option is a properitary optimisation which can be used to prevent from the serialization overhead and provide a better performance, but as said the application need to be designed for that.
For a robust API it is recommended to not use pass-by-value and provide proper interfaces marked as @Local which clarifies that these methods are save to be invoked with object references.
If such application is migrated to EAP 7.2.0 there is an Content from issues.jboss.org is not included.issue JBEAP-16573 which cause NotSerializableException failure even if <in-vm-remote-interface-invocation pass-by-value="false"> is configured when an Exception is thrown as the Exception will be serialized.
Root Cause
The EJB specification contains different ways to invoke methods for such bean
- NoInterfaceView, the bean is marked as SessionBean but does not declare any interface (since 3.1)
All public methods are exposed and are visible inside the same deployment - @Local interface
The bean must be visible within the same application and use call-by-reference
It might be vendor specific that the bean is visible within the same server instance for other deployed applications - @Remote interface
The bean is visible local and remote and it is possible to make invocations across different JVM's
Because of this all objects which can be transfered (method parameter and return value, all declared Exceptions) must be serializable for this contract
Diagnostic Steps
- Is the invocation remote?
- Is the invocation within the same JVM and
<in-vm-remote-interface-invocation pass-by-value="false">is configured? - Are all method parameters, return value and declared checked Exceptions and inner objects marked with @Serializable?
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.