4 Replies Latest reply on Mar 13, 2008 12:15 AM by ron_sigal

    Question about Remoting, Marshalling, and EJBs

    ron_sigal

      I'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

        • 1. Re: Question about Remoting, Marshalling, and EJBs
          bdecoste

          1) I don't think so

          2) W currently add the tx id to the client side invocation if there's an active tx. I don't think adding a tx context to the remoting marshalling would have any impact on us - you would just be adding tx context to the response? What would client side remoting do with the response context?

          3) The only explicit marshalling ejb3 does is for calls to a @Remote interface so the call is call-by value per the spec. We use org.jboss.serial.io.MarshalledObjectForLocalCalls(invocation).

          • 2. Re: Question about Remoting, Marshalling, and EJBs
            galder.zamarreno

            Re 1: I haven't seen any customer asking for this.

            Re 2: why would InvocationMarshaller need to be used when sending back a response from the server to the client? transaction propagation is a one way system, from client to server whereas encryption works both ways. I don't think we should marshall unnecessary data.

            Ron, if you do this, bear in mind the unified invoker unit tests I added based on mock remoting objects. They're standalone and fast to execute :). Let me know if you need a hand to fit in any tests you create for this within AS codebase.

            In fact, one of the things I didn't get around to doing was creating remoting mock objects so that IM and IU were used. Marshalling happens too down the stack in remoting and cannot be mocked easily (i.e. mock objects to achieve this would be far too complicated), so ended up repeating the code from IM, IU in the tests. Please bear in mind this and let me know if you can think of a better way to set up Remoting mock objects for this.

            • 3. Re: Question about Remoting, Marshalling, and EJBs
              timfox

               

              "ron.sigal@jboss.com" wrote:

              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?



              From JBM POV, we only use the bisocket and http transports, so as long as it doesn't effect those transports, we don't care

              • 4. Re: Question about Remoting, Marshalling, and EJBs
                ron_sigal

                Thanks, everyone, for your rapid replies.

                1. I've gone ahead and added this feature, and I don't think it will have any impact on any other projects.

                1a) Upon further inspection, I see that org.jboss.invocation.unified.marshall.InvocationMarshaller acts only upon InvocationRequests, so in the server-to-client direction it has no effect.

                1b) Just in case, I added the parameter org.jboss.remoting.transport.rmi.RMIServerInvoker.RMI_ONEWAY_MARSHALLING (actual value "rmiOnewayMarshalling"), which, when set to "true", will cause the RMI transport to revert to its current marshalling behavior.

                2. Galder, where are those "unified invoker unit tests" tests you mentioned? I'd like to take a look at them.

                3. Bill, where is org.jboss.serial.io.MarshalledObjectForLocalCalls?

                4. Finally, Galder, note that it's never to early to start agitating for a meeting in Neuchatel next September. :-)

                -Ron