[jboss-remoting-commits] JBoss Remoting SVN: r3471 - remoting2/branches/2.x/src/main/org/jboss/remoting.

jboss-remoting-commits at lists.jboss.org jboss-remoting-commits at lists.jboss.org
Fri Feb 22 04:36:23 EST 2008


Author: ron.sigal at jboss.com
Date: 2008-02-22 04:36:22 -0500 (Fri, 22 Feb 2008)
New Revision: 3471

Modified:
   remoting2/branches/2.x/src/main/org/jboss/remoting/MicroRemoteClientInvoker.java
Log:
JBREM-900: Introduced a WeakHashMap of unmarshallers.

Modified: remoting2/branches/2.x/src/main/org/jboss/remoting/MicroRemoteClientInvoker.java
===================================================================
--- remoting2/branches/2.x/src/main/org/jboss/remoting/MicroRemoteClientInvoker.java	2008-02-21 18:17:50 UTC (rev 3470)
+++ remoting2/branches/2.x/src/main/org/jboss/remoting/MicroRemoteClientInvoker.java	2008-02-22 09:36:22 UTC (rev 3471)
@@ -7,13 +7,16 @@
 import org.jboss.remoting.marshal.MarshalFactory;
 import org.jboss.remoting.marshal.Marshaller;
 import org.jboss.remoting.marshal.UnMarshaller;
+import org.jboss.remoting.marshal.UpdateableClassloaderUnMarshaller;
 import org.jboss.remoting.transport.ClientInvoker;
 import org.jboss.util.id.GUID;
 
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.WeakHashMap;
 
 /**
  * MicroRemoteClientInvoker is an abstract client part handler that implements the bulk of the heavy
@@ -37,7 +40,7 @@
 
    protected boolean connected = false;
    private Marshaller marshaller;
-   private UnMarshaller unmarshaller;
+   private Map unmarshallers = new WeakHashMap();
    private String dataType;
    private final Object clientLeaseLock = new Object();
    private LeasePinger leasePinger = null;
@@ -65,9 +68,8 @@
 
       if (trace) { log.trace(this + "(" + (++invokeCount) + ") invoking " + invocationReq); }
 
+      // Set up marshaller.
       Marshaller marshaller = getMarshaller();
-      UnMarshaller unmarshaller = getUnMarshaller();
-
       if (marshaller == null)
       {
          // try by locator (in case marshaller class name specified)
@@ -80,34 +82,61 @@
             {
                // went as far as possible to find a marshaller, will have to give up
                throw new InvalidMarshallingResource(
-                  "Can not find a valid marshaller for data type: " + getDataType());
+                     "Can not find a valid marshaller for data type: " + getDataType());
             }
-            setMarshaller(marshaller);
          }
+         setMarshaller(marshaller);
       }
 
-      if (unmarshaller == null)
+      // Set up unmarshaller.
+      UnMarshaller unmarshaller = null;
+      RemotingClassLoader rcl = null;
+      synchronized (unmarshallers)
       {
-         // creating a new classloader containing the remoting class loader (for remote classloading)
-         // and the current thread's class loader.  This allows to load remoting classes as well as
-         // user's classes.
-         ClassLoader remotingClassLoader =
-            new RemotingClassLoader(getClassLoader(), Thread.currentThread().getContextClassLoader());
-         
-         // try by locator (in case unmarshaller class name specified)
-         unmarshaller = MarshalFactory.getUnMarshaller(getLocator(), getClassLoader());
+         unmarshaller = getUnMarshaller();
          if (unmarshaller == null)
          {
-            unmarshaller = MarshalFactory.getUnMarshaller(getDataType(), getSerializationType());
+            // try by locator (in case unmarshaller class name specified)
+            unmarshaller = MarshalFactory.getUnMarshaller(getLocator(), getClassLoader());
             if (unmarshaller == null)
             {
-               // went as far as possible to find a unmarshaller, will have to give up
-               throw new InvalidMarshallingResource(
-                  "Can not find a valid unmarshaller for data type: " + getDataType());
+               unmarshaller = MarshalFactory.getUnMarshaller(getDataType(), getSerializationType());
+               if (unmarshaller == null)
+               {
+                  // went as far as possible to find a unmarshaller, will have to give up
+                  throw new InvalidMarshallingResource(
+                        "Can not find a valid unmarshaller for data type: " + getDataType());
+               }
             }
             setUnMarshaller(unmarshaller);
          }
-         unmarshaller.setClassLoader(remotingClassLoader);
+
+         // Each unmarshaller gets a RemotingClassloader classloader containing the 
+         // remoting class loader (for remote classloading) and the current thread's
+         // class loader.  This allows to load remoting classes as well as user's
+         // classes.  If possible, will simply reset context classloader on existing
+         // RemotingClassLoader.
+         ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+         if (unmarshaller instanceof UpdateableClassloaderUnMarshaller)
+         {
+            UpdateableClassloaderUnMarshaller uclum = (UpdateableClassloaderUnMarshaller) unmarshaller;
+            ClassLoader cl = uclum.getClassLoader();
+            if (cl instanceof RemotingClassLoader)
+            {
+               rcl = (RemotingClassLoader) cl;
+               rcl.setUserClassLoader(contextClassLoader);
+            }
+            else
+            {
+               rcl = new RemotingClassLoader(getClassLoader(), contextClassLoader);
+               unmarshaller.setClassLoader(rcl);
+            }
+         }
+         else
+         {
+            rcl = new RemotingClassLoader(getClassLoader(), contextClassLoader);
+            unmarshaller.setClassLoader(rcl);  
+         }
       }
 
       // if raw, then send only param of invocation request
@@ -122,9 +151,17 @@
          payload = invocationReq;
       }
 
-      returnValue =
-         transport(invocationReq.getSessionId(), payload, metadata, marshaller, unmarshaller);
-
+      try
+      {
+         String sessionId = invocationReq.getSessionId();
+         returnValue = transport(sessionId, payload, metadata, marshaller, unmarshaller);
+      }
+      finally
+      {
+         // Delete reference to current thread's context classloader.
+         rcl.unsetUserClassLoader();
+      }
+      
       // Now check if is remoting response and process
       if (returnValue instanceof InvocationResponse)
       {
@@ -313,12 +350,18 @@
 
    public void setUnMarshaller(UnMarshaller unmarshaller)
    {
-      this.unmarshaller = unmarshaller;
+      synchronized (unmarshallers)
+      {
+         unmarshallers.put(Thread.currentThread().getContextClassLoader(), unmarshaller);
+      }
    }
 
    public UnMarshaller getUnMarshaller()
    {
-      return this.unmarshaller;
+      synchronized (unmarshallers)
+      {
+         return (UnMarshaller)unmarshallers.get(Thread.currentThread().getContextClassLoader());
+      }
    }
    
    public String getSessionId()




More information about the jboss-remoting-commits mailing list