3 Replies Latest reply on Jun 19, 2012 8:38 AM by jaikiran

    Losing objects during serialization...

    kdolan1

      I am having an issue calling an EJB method from the web-tier...it's losing some of my objects.  First, I'll say that I got around this by adding <in-vm-remote-interface-invocation pass-by-value="false"/> to my standalone.xml file.  However, I'm hoping someone may read this and have an a-ha moment that I am just not seeing why it doesn't work w/ pass-by-value=true (default).

       

      I'm upgrading from JBoss 4.0.1sp1 to 7.1.1.  My EJB defaults to a remote EJB because I'm not doing anything special to make it "local" (e.g., no annotations, no <local> deployment descriptor elements).  In JBoss 4 I'm guessing it was smart enough to detect all calls were local and just passed by reference w/o complaint.  W/ JBoss 7 this is not so - I can tell because I had to make a bunch of classes Serializable.

       

      To my issue...

       

      I have an object I'll call MyObj.  It has many data members, some primitive and others w/ other data members, etc.  Somewhere in the mix are 2 variables of type DocumentImpl and DeferredDocumentImpl (both in org.apache.xerces.dom package).  I should be using the classes that ship w/ JBoss 7 (org.apache.xerces module).  The apache documentation says that these 2 classes are Serializable.  The class that directly contains these classes and all ancestors up to MyObj are Serializable and nothing is marked transient.  So I cannot figure out why when I make my call to my EJB, in the web-tier I have actual object instances assigned to my variables and once in my EJB they are null.

       

      I ran my debugger and put a breakpoint once in my EJB.  The call stack is below and I've marked w/ asterisks exactly where my objects are lost.  Next, I turned TRACE debugging on for org.jboss.as.ejb3 and org.jboss.as.ejb to see if there was some valuable information I was missing only logging WARN and ERROR.  Sorry, not much.  I then looked at the code for LocalEjbReceiver.processInvocation() and found where it calls clone() for parameters.

       

      1. object should not be null

      2. DocumentImpl/DeferredDocumentImpl are not primitives

      3. allowPassByReference is not true (at the time)

      4. cloner.clone() is not appearing to throw an exception

       

      So at this point, I am puzzled why object instances are lost and am really just curious to know why.  All thoughts are welcome.  But again, with that said I've changed my configuration to be pass by reference so I'm able to move on.

       

      MyEjbImpl.myMethod(MyObj) line: 812

      NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]

      NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39

      DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25

      Method.invoke(Object, Object...) line: 597

      ManagedReferenceMethodInterceptorFactory$ManagedReferenceMethodInterceptor.processInvocation(InterceptorContext) line: 72

      InterceptorContext.proceed() line: 288

      WeavedInterceptor.processInvocation(InterceptorContext) line: 53

      UserInterceptorFactory$1.processInvocation(InterceptorContext) line: 36

      InterceptorContext.proceed() line: 288

      SBInvocationInterceptor.processInvocation(InterceptorContext) line: 47

      InterceptorContext.proceed() line: 288

      InitialInterceptor.processInvocation(InterceptorContext) line: 21

      InterceptorContext.proceed() line: 288

      ChainedInterceptor.processInvocation(InterceptorContext) line: 61

      ComponentDispatcherInterceptor.processInvocation(InterceptorContext) line: 53

      InterceptorContext.proceed() line: 288

      PooledInstanceInterceptor.processInvocation(InterceptorContext) line: 51

      InterceptorContext.proceed() line: 288

      CMTTxInterceptor.invokeInCallerTx(InterceptorContext, Transaction, EJBComponent) line: 202

      CMTTxInterceptor.required(InterceptorContext, EJBComponent, int) line: 306

      CMTTxInterceptor.processInvocation(InterceptorContext) line: 190

      InterceptorContext.proceed() line: 288

      EJBRemoteTransactionPropagatingInterceptor.processInvocation(InterceptorContext) line: 80

      InterceptorContext.proceed() line: 288

      CurrentInvocationContextInterceptor.processInvocation(InterceptorContext) line: 41

      InterceptorContext.proceed() line: 288

      LoggingInterceptor.processInvocation(InterceptorContext) line: 59

      InterceptorContext.proceed() line: 288

      EjbExceptionTransformingInterceptorFactories$1.processInvocation(InterceptorContext) line: 65

      InterceptorContext.proceed() line: 288

      NamespaceContextInterceptor.processInvocation(InterceptorContext) line: 50

      InterceptorContext.proceed() line: 288

      AdditionalSetupInterceptor.processInvocation(InterceptorContext) line: 32

      InterceptorContext.proceed() line: 288

      TCCLInterceptor.processInvocation(InterceptorContext) line: 45

      InterceptorContext.proceed() line: 288

      ChainedInterceptor.processInvocation(InterceptorContext) line: 61

      ViewService$View.invoke(InterceptorContext) line: 165

      LocalEjbReceiver.processInvocation(EJBClientInvocationContext, EJBReceiverInvocationContext) line: 179

       

       

      *** The method below has references to my internal objects in this.parameters.  The method above does not. ***

       

       

      EJBClientInvocationContext.sendRequest() line: 179

      TransactionInterceptor.handleInvocation(EJBClientInvocationContext) line: 43

      EJBClientInvocationContext.sendRequest() line: 181

      ReceiverInterceptor.handleInvocation(EJBClientInvocationContext) line: 128

      EJBClientInvocationContext.sendRequest() line: 181

      EJBInvocationHandler<T>.doInvoke(EJBInvocationHandler<T>, boolean, T, Method, Object[], EJBClientContext) line: 136

      EJBInvocationHandler<T>.doInvoke(T, Method, Object[]) line: 121

      EJBInvocationHandler<T>.invoke(Object, Method, Object[]) line: 104

      $Proxy12.myMethod(MyObj) line: not available

      MyEjbDelegate(MentorDelegate).myMethod(MyObj) line: 1190

       

       

      Thanks

      Kelly

        • 1. Re: Losing objects during serialization...
          jaikiran

          What exactly is the type of the objects/variables that go null? Also if possible, can you attach a small reproducible application?

          • 2. Re: Losing objects during serialization...
            kdolan1

            The objects are of type org.apache.xerces.dom.DocumentImpl and org.apache.xerces.dom.DeferredDocumentImpl.

             

            In putting together some additional information, I wonder if I have stumbled onto the reason.  The MyObj class is a subclass and the 2 variables in question are actually owned by a parent class that is NOT serializable (this I just noticed now). 

            Yesterday, I ran into http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html which talks to subtypes of non-serializable classes.  The parent class has other variables and these are cloned correctly but they are set in its no-arg constructor whereas the 2 variables in question are not.  For example:

             

            public abstract class MyBaseObj {

               private Document docImpl;

               private Document deferredDocImpl;

               private List aList;

               private Map aMap;

             

              public MyBaseObj() {

                  aList = new ArrayList();

                  aMap = new HashMap();

               }

            }

            public class MyObj extends MyBaseObj implements Serializable {

               // its vars, constructor and methods - none of which take responsibility for re-setting the docImpl or deferredDocImpl classes

            }

             

            MyObj is the object passed across an EJB boundary and therefore serialized.  BTW - I also bet the only reason I think the aList and aMap variables are re-set correctly are because they are empty collections when I make the EJB call.  I bet if they contained items, the items would be gone.

             

            Do you agree?

            • 3. Re: Losing objects during serialization...
              jaikiran

              Yes, you are right. The entire object hierarchy is expected to be serializable. Having said that, I would think that throwing a NotSerailizableException would have been more appropriate in cases like these.