Question about Remoting, Marshalling, and EJBs
ron_sigal Mar 8, 2008 6:27 PMI'm looking at an old Remoting issue, JBREM-167 "RMI Invoker does not use true remoting marshalling/unmarshalling" and I have a question. This issue concerns the Remoting RMI transport, which, as an alternative to the more commonly used "socket" transport, makes invocations using Java RMI. If the "jboss.remoting:service=Connector,transport=socket" Connector in conf/jboss-service.xml were configured to use the RMI tranport, then EJB2 calls would be transported by Java RMI.
Currently, the RMI transport uses org.jboss.invocation.unified.marshall.InvocationMarshaller to marshal invocations on the client side and org.jboss.invocation.unified.marshall.InvocationUnMarshaller to unmarshal invocations on the server side. Their main function, other than serializing and deserializing the invocation, is to add and remove transaction context information:
// From InvocationMarshaller: public Object addDecoration(Object dataObject) throws IOException { if(dataObject instanceof InvocationRequest) { InvocationRequest remoteInv = (InvocationRequest) dataObject; if(remoteInv.getParameter() instanceof Invocation) { Invocation inv = (Invocation) remoteInv.getParameter(); MarshalledInvocation marshInv = new MarshalledInvocation(inv); if(inv != null) { // now that have invocation object related to ejb invocations, // need to get the possible known payload objects and make sure // they get serialized. try { marshInv.setTransactionPropagationContext(getTransactionPropagationContext()); } catch(SystemException e) { log.error("Error setting transaction propagation context.", e); throw new IOException("Error setting transaction context. Message: " + e.getMessage()); } // reset the invocation parameter within remote invocation remoteInv.setParameter(marshInv); } else { //Should never get here, but will check anyways log.error("Attempting to marshall Invocation but is null. Can not proceed."); throw new IOException("Can not process data object due to the InvocationRequest's parameter being null."); } } } return dataObject; }
and
// From InvocationUnMarshaller: public Object removeDecoration(Object obj) throws IOException { if(obj instanceof InvocationRequest) { InvocationRequest remoteInv = (InvocationRequest) obj; Object param = remoteInv.getParameter(); if(param instanceof MarshalledInvocation) { MarshalledInvocation mi = (MarshalledInvocation) param; Object txCxt = mi.getTransactionPropagationContext(); if(txCxt != null) { TransactionPropagationContextImporter tpcImporter = TransactionPropagationContextUtil.getTPCImporter(); mi.setTransaction(tpcImporter.importTransactionPropagationContext(txCxt)); } } } return obj; }
On the other hand, when the server returns a response, no marshalling is performed on the server side and no unmarshalling is performed on the client side: the response is passed directly to the RMI runtime. The point of JBREM-167 is to change the RMI server invoker to use a configured marshaller and to change the RMI client invoker to use a configured unmarshaller. This way, someone could interpose, for example, encrypting or compressing marshaller/unmarshallers, which is not currently possible.
My questions:
1. Does anyone care about having this feature?
2. This change would mean that the InvocationMarshaller would be used on the server side when returning a response and InvocationUnMarshaller would be used on the client side to unmarshal the response. Would adding and removing transaction context in the server-to-client direction have any implications?
3. Since EJB3 handles transaction information in an interceptor and doesn't, by default, configure any marshaller or unmarshaller, am I right that this issue is irrelevant to EJB3?
Thanks,
Ron