How to enable EJB pass-by-reference in JBoss EAP 6 ?
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 6.x
Issue
-
EJB AinEAR 1callsEJB BinEAR 2. The calls work fine, but there is performance issues due to serialization/deserialization. How can one avoid this overhead? -
We have set the following option in the
JBoss ejb3subsystem:
<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 the ejb interfaces and transfer objects, a ClassCastException is thrown. Isn't JBoss supposed to only use pass-by-reference if the classloaders are the same?
- The
ClassCastExceptionoccurrs when trying to read an object from the list passed at EJB call in as shown below:
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 );
}
-
By default which mechanism (
pass-by-referenceorpass-by-value) does the JBoss use ? -
What is the ideal scenario to use
pass-by-reference? - What is the difference between using
@Localand@Remote? - Does EAP 6 support the system property
-Dorg.jboss.ejb3.remoting.IsLocalInterceptor.passByRef=true? This was present in EAP 5
Resolution
-
The recommended approach is to use the
localinterface wheneverpass-by-referenceis to be used. -
If using
localinterface is not feasible, There is aJBossspecific (non-JavaEE specification) option to haveJBossusepass-by-referencewhenremoteinterfaces are used. Please read theNotesandWarningscarefully below. -
By default:
pass-by-valuemechanism is being used if your are looking forEJB's Remote interfaceno matter whether it is localJVMor remoteJVMpass-by-referencemechanism is always being used if you are callingEJB's Local interface
-
Using
pass-by-referenceexplicitly makes sense only when theEJB's Remote interfaceis 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-valuesemantic by setting a per application level configuration which then usespass-by-referencesemantics forin-VMcalls on theremoteinterfaces of the bean. The current setting is allowed in ajboss-ejb-client.xmlof 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.xmlis packaged in the top level deployment in theMETA-INFdirectory. 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.xmlwould go in theWEB-INFfolder of this war. However if the war is a sub deployment of an ear, then thejboss-ejb-client.xmlwould go in the ear'sMETA-INFfolder. If thejboss-ejb-client.xmlis in a sub deployment then there will be aWARNmessage 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-valuecan 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
JBosswill 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.
Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.
