You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rpc-dev@xml.apache.org by Daniel Rall <dl...@finemaltcoding.com> on 2002/02/19 01:19:41 UTC

[PATCH] XmlRpcServer$Invoker Method cache

This is a bit rushed (so there may be dumb errors), but I wanted to
send it out for Jon to look over (he's helping out with the
performance issues -- he suggested this change).

                             Thanks, Dan

Index: XmlRpcServer.java
===================================================================
RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcServer.java,v
retrieving revision 1.11
diff -u -u -r1.11 XmlRpcServer.java
--- XmlRpcServer.java	18 Feb 2002 23:22:29 -0000	1.11
+++ XmlRpcServer.java	19 Feb 2002 00:16:17 -0000
@@ -376,12 +376,32 @@
 // This class uses Java Reflection to call methods matching an XML-RPC call
 class Invoker implements XmlRpcHandler
 {
+    private static Class objectClass;
+    static
+    {
+        try
+        {
+            objectClass = Class.forName("java.lang.Object");
+        }
+        catch (ClassNotFoundException e)
+        {
+            System.err.println(e.toString());
+            //throw new ExceptionInInitializer(e.getMessage());
+        }
+    }
+
+    /**
+     * A mapping of method names to <code>Method</code> objects.
+     */
+    private Hashtable methodsByName;
 
     private Object invokeTarget;
+
     private Class targetClass;
 
     public Invoker(Object target)
     {
+        methodsByName = new Hashtable();
         invokeTarget = target;
         targetClass = invokeTarget instanceof Class ? (Class) invokeTarget :
                 invokeTarget.getClass();
@@ -390,12 +410,16 @@
     }
 
 
-    // main method, sucht methode in object, wenn gefunden dann aufrufen.
-    public Object execute (String methodName,
-            Vector params) throws Exception
+    /**
+     * Main method, sucht methode in object, wenn gefunden dann
+     * aufrufen.
+     *
+     * @param methodName The name of the method to invoke.
+     * @param params The method parameters.
+     */
+    public Object execute (String methodName, Vector params)
+        throws Exception
     {
-
-
         // Array mit Classtype bilden, ObjectAry mit Values bilden
         Class[] argClasses = null;
         Object[] argValues = null;
@@ -417,36 +441,10 @@
             }
         }
 
-        // Methode da ?
-        Method method = null;
-
-        if (XmlRpc.debug)
-        {
-            System.err.println("Searching for method: " + methodName);
-            for (int i = 0; i < argClasses.length; i++)
-                System.err.println("Parameter " + i + ": " +
-                        argClasses[i] + " = " + argValues[i]);
-        }
+        // Let's play, "Find that Method object!"
+        Method method = findMethod(methodName, argClasses, argValues);
 
-        try
-        {
-            method = targetClass.getMethod(methodName, argClasses);
-        }
-        // Wenn nicht da dann entsprechende Exception returnen
-        catch (NoSuchMethodException nsm_e)
-        {
-            throw nsm_e;
-        }
-        catch (SecurityException s_e)
-        {
-            throw s_e;
-        }
-
-        // our policy is to make all public methods callable except the ones defined in java.lang.Object
-        if (method.getDeclaringClass () == Class.forName ("java.lang.Object"))
-            throw new XmlRpcException (0, "Invoker can't call methods defined in java.lang.Object");
-
-        // invoke
+        // Invoke the method.
         Object returnValue = null;
         try
         {
@@ -475,4 +473,48 @@
         return returnValue;
     }
 
+    /**
+     * Finds <code>methodName</code>, caching it if it is not already
+     * in the cache.
+     *
+     * @param methodName The name of the <code>Method</code> to find.
+     * @return The <code>Method</code> object named by
+     * <code>methodName</code>.
+     */
+    protected Method findMethod(String methodName, Class[] argClasses,
+                                Object[] argValues)
+        throws XmlRpcException, NoSuchMethodException
+    {
+        // Let's play, "Find that Method object!"
+        Method method = (Method) methodsByName.get(methodName);
+        if (method == null)
+        {
+            // Not yet cached.
+            synchronized (methodsByName)
+            {
+                if (XmlRpc.debug)
+                {
+                    System.err.println("Searching for method: " + methodName);
+                    for (int i = 0; i < argClasses.length; i++)
+                    {
+                        System.err.println("Parameter " + i + ": " +
+                                           argClasses[i] + "=" + argValues[i]);
+                    }
+                }
+
+                method = targetClass.getMethod(methodName, argClasses);
+
+                // Our policy is to make all public methods callable
+                // except for the ones defined in java.lang.Object.
+                if (method.getDeclaringClass() == objectClass)
+                {
+                    throw new XmlRpcException(0, "Invoker can't call methods " +
+                                              "defined in java.lang.Object");
+                }
+
+                methodsByName.put(methodName, method);
+            }
+        }
+        return method;
+    }
 }