EJB pass-by-reference in JBoss EAP 7 / 6
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 7
- 6
Issue
-
EJB A
inEAR 1
callsEJB B
inEAR 2
. The calls succeed but have performance issues due to serialization. -
We have set the following option in the JBoss EAP
ejb3
subsystem:<subsystem xmlns="urn:jboss:domain:ejb3:1.3"> ... <in-vm-remote-interface-invocation pass-by-value="false"/> ... </subsystem>
But when there are two
ears
packaging theejb
interfaces and transfer objects, aClassCastException
is thrown. Shouldn'tpass-by-reference
be used only if the classloaders are the same? -
The
ClassCastException
occurs when trying to read an object from the list passed from an EJB with code like:public TransferReturnValue hellos ( List<TransferParameter> params ) { for(TransferParameter param : params) { // ClassCastException is thrown here log.info("received param: " + param.getValue()); } return new TransferReturnValue ( "Hello " + params ); }
-
Which mechanism is the default for same-VM EJBs:
pass-by-reference
orpass-by-value
? -
What is the ideal scenario to use
pass-by-reference
? - What is the difference between using
@Local
and@Remote
? - Does JBoss EAP 6 or 7 support the system property
-Dorg.jboss.ejb3.remoting.IsLocalInterceptor.passByRef=true
from version 5?
Resolution
-
The recommended approach is to use the
local
interface wheneverpass-by-reference
is to be used. -
If using
local
interface is not feasible, There is aJBoss
specific (non-JavaEE specification) option to haveJBoss
usepass-by-reference
whenremote
interfaces are used. Please read theNotes
andWarnings
carefully below. -
By default:
pass-by-value
mechanism is being used if your are looking forEJB's Remote interface
no matter whether it is localJVM
or remoteJVM
pass-by-reference
mechanism is always being used if you are callingEJB's Local interface
-
Using
pass-by-reference
explicitly makes sense only when theEJB's Remote interface
is being called within the same JVM.
Note: pass-by-reference
can only be used if the classloader
of the EJB
interfaces & transfer objects is the same on the client application
and EJB side
. If pass-by-value="false"
is specified means "pass-by-reference" is being used then JBoss EAP 6
will do a shallow
check instead of deep
check for class loaders.
Warning: This shallow check means that if an object contains other objects such as a List<MyObject>
for example, JBoss EAP
will only look at the List object and not at the objects contained within the List object. This means that the objects in the List itself could be loaded with different classloaders and result in a ClassCastException
. JBoss EAP
does not perform a deep check to confirm that there would not be a ClassCastException
, because to confirm that JBoss
would have to check the entire object graph and doing this is an expensive operation of cloning/marshalling and this is performed only in the case of pass-by-value.
Disable pass-by-value
(= enable pass-by-reference
) at the client level :
-
Individual applications can override the default
pass-by-value
semantic by setting a per application level configuration which then usespass-by-reference
semantics forin-VM
calls on theremote
interfaces of the bean. The current setting is allowed in ajboss-ejb-client.xml
of the application as follows:<jboss-ejb-client xmlns="urn:jboss:ejb-client:1.0"> <client-context> <ejb-receivers local-receiver-pass-by-value="false"/> </client-context> </jboss-ejb-client>
Note:
- The
jboss-ejb-client.xml
is packaged in the top level deployment in theMETA-INF
directory. So if the top level deployment is anear
, you would need to package it inmy.ear/META-INF/
. -
A top level deployment is a deployment that is not a sub deployment. A war in the deployments directory would be a top level deployment and the
jboss-ejb-client.xml
would go in theWEB-INF
folder of this war. However if the war is a sub deployment of an ear, then thejboss-ejb-client.xml
would go in the ear'sMETA-INF
folder. If thejboss-ejb-client.xml
is in a sub deployment then there will be aWARN
message printed as shown below indicating it is not in the correct location:WARN [org.jboss.as.ee] (MSC service thread 1-8) JBAS011013: /$JBOSS_HOME/standalone/deployments/client.ear/client.war/WEB-INF/jboss-ejb-client.xml in subdeployment ignored. jboss-ejb-client.xml is only parsed for top level deployments.
- The
-
Attached is an example, which demonstrates how you are configure, identify and make the 'pass-by-reference' work with
jboss-ejb-client.xml
.
Disable pass-by-value
(= enable pass-by-reference
) globally :
-
This is how
pass-by-value
can be disabled at the subsystem level as described below :-
With the CLI management:
$ bin/jboss-cli.sh -c [standalone@localhost:9999 /] /subsystem=ejb3:write-attribute(name=in-vm-remote-interface-invocation-pass-by-value, value=false)
-
The XML results looks like this:
<subsystem xmlns="urn:jboss:domain:ejb3:1.2"> ... <!-- Disable pass-by-value for in-vm remote interface invocations on EJBs --> <in-vm-remote-interface-invocation pass-by-value="false"/> </subsystem>
Note: This is not recommended as it will affect all applications and
JBoss
will perform the shallow check for all applications deployed. -
Attachments
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.
Comments