[jboss-cvs] javassist SVN: r676 - in trunk: src/main/javassist/util/proxy and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Oct 25 12:38:40 EDT 2012


Author: chiba
Date: 2012-10-25 12:38:40 -0400 (Thu, 25 Oct 2012)
New Revision: 676

Modified:
   trunk/javassist.jar
   trunk/src/main/javassist/util/proxy/MethodHandler.java
   trunk/src/main/javassist/util/proxy/ProxyFactory.java
   trunk/src/main/javassist/util/proxy/RuntimeSupport.java
   trunk/src/test/javassist/JvstTest.java
   trunk/src/test/javassist/proxyfactory/ProxyFactoryTest.java
   trunk/src/test/test/javassist/proxy/ProxySimpleTest.java
Log:
fixed JASSIST-163.  Eager initialization has been implemented.

Modified: trunk/javassist.jar
===================================================================
(Binary files differ)

Modified: trunk/src/main/javassist/util/proxy/MethodHandler.java
===================================================================
--- trunk/src/main/javassist/util/proxy/MethodHandler.java	2012-10-20 10:57:51 UTC (rev 675)
+++ trunk/src/main/javassist/util/proxy/MethodHandler.java	2012-10-25 16:38:40 UTC (rev 676)
@@ -22,7 +22,7 @@
  * The interface implemented by the invocation handler of a proxy
  * instance.
  *
- * @see ProxyFactory#setHandler(MethodHandler)
+ * @see Proxy#setHandler(MethodHandler)
  */
 public interface MethodHandler {
     /**
@@ -33,7 +33,7 @@
      * @param thisMethod    the overridden method declared in the super
      *                      class or interface.
      * @param proceed       the forwarder method for invoking the overridden 
-     *                      method.  It is null if the overridden mehtod is
+     *                      method.  It is null if the overridden method is
      *                      abstract or declared in the interface.
      * @param args          an array of objects containing the values of
      *                      the arguments passed in the method invocation

Modified: trunk/src/main/javassist/util/proxy/ProxyFactory.java
===================================================================
--- trunk/src/main/javassist/util/proxy/ProxyFactory.java	2012-10-20 10:57:51 UTC (rev 675)
+++ trunk/src/main/javassist/util/proxy/ProxyFactory.java	2012-10-25 16:38:40 UTC (rev 676)
@@ -27,6 +27,7 @@
 import java.lang.ref.WeakReference;
 
 import javassist.CannotCompileException;
+import javassist.NotFoundException;
 import javassist.bytecode.*;
 
 /*
@@ -204,7 +205,7 @@
 
     private static final String SERIAL_VERSION_UID_FIELD = "serialVersionUID";
     private static final String SERIAL_VERSION_UID_TYPE = "J";
-    private static final int SERIAL_VERSION_UID_VALUE = -1;
+    private static final long SERIAL_VERSION_UID_VALUE = -1L;
 
     /**
      * If true, a generated proxy class is cached and it will be reused
@@ -736,8 +737,10 @@
         // HashMap allMethods = getMethods(superClass, interfaces);
         // int size = allMethods.size();
         makeConstructors(classname, cf, pool, classname);
-        int s = overrideMethods(cf, pool, classname);
-        addMethodsHolder(cf, pool, classname, s);
+
+        ArrayList forwarders = new ArrayList();
+        int s = overrideMethods(cf, pool, classname, forwarders);
+        addClassInitializer(cf, pool, classname, s, forwarders);
         addSetter(classname, cf, pool);
         if (!hasGetHandler)
             addGetter(classname, cf, pool);
@@ -875,8 +878,8 @@
         cf.setInterfaces(list);
     }
 
-    private static void addMethodsHolder(ClassFile cf, ConstPool cp,
-                                         String classname, int size)
+    private static void addClassInitializer(ClassFile cf, ConstPool cp,
+                                    String classname, int size, ArrayList forwarders)
         throws CannotCompileException
     {
         FieldInfo finfo = new FieldInfo(cp, HOLDER, HOLDER_TYPE);
@@ -884,18 +887,61 @@
         cf.addField(finfo);
         MethodInfo minfo = new MethodInfo(cp, "<clinit>", "()V");
         minfo.setAccessFlags(AccessFlag.STATIC);
-        Bytecode code = new Bytecode(cp, 0, 0);
+        setThrows(minfo, cp, new Class[] { ClassNotFoundException.class });
+
+        Bytecode code = new Bytecode(cp, 0, 2);
         code.addIconst(size * 2);
         code.addAnewarray("java.lang.reflect.Method");
+        final int varArray = 0;
+        code.addAstore(varArray);
+
+        // forName() must be called here.  Otherwise, the class might be
+        // invisible.
+        code.addLdc(classname);
+        code.addInvokestatic("java.lang.Class",
+                "forName", "(Ljava/lang/String;)Ljava/lang/Class;");
+        final int varClass = 1;
+        code.addAstore(varClass);
+
+        Iterator it = forwarders.iterator();
+        while (it.hasNext()) {
+            Find2MethodsArgs args = (Find2MethodsArgs)it.next();
+            callFind2Methods(code, args.methodName, args.delegatorName,
+                             args.origIndex, args.descriptor, varClass, varArray);
+        }
+
+        code.addAload(varArray);
         code.addPutstatic(classname, HOLDER, HOLDER_TYPE);
-        // also need to set serial version uid
-        code.addLconst(-1L);
+
+        code.addLconst(SERIAL_VERSION_UID_VALUE);
         code.addPutstatic(classname, SERIAL_VERSION_UID_FIELD, SERIAL_VERSION_UID_TYPE);
         code.addOpcode(Bytecode.RETURN);
         minfo.setCodeAttribute(code.toCodeAttribute());
         cf.addMethod(minfo);
     }
 
+    /**
+     * @param thisMethod        might be null.
+     */
+    private static void callFind2Methods(Bytecode code, String superMethod, String thisMethod,
+                                         int index, String desc, int classVar, int arrayVar) {
+        String findClass = RuntimeSupport.class.getName();
+        String findDesc
+            = "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V";
+
+        code.addAload(classVar);
+        code.addLdc(superMethod);
+        if (thisMethod == null)
+            code.addOpcode(Opcode.ACONST_NULL);
+        else
+            code.addLdc(thisMethod);
+
+        code.addIconst(index);
+        code.addLdc(desc);
+        code.addAload(arrayVar);
+        code.addInvokestatic(findClass, "find2Methods", findDesc);
+    }
+
     private static void addSetter(String classname, ClassFile cf, ConstPool cp)
         throws CannotCompileException
     {
@@ -925,7 +971,7 @@
         cf.addMethod(minfo);
     }
 
-    private int overrideMethods(ClassFile cf, ConstPool cp, String className)
+    private int overrideMethods(ClassFile cf, ConstPool cp, String className, ArrayList forwarders)
         throws CannotCompileException
     {
         String prefix = makeUniqueName("_d", signatureMethods);
@@ -938,7 +984,7 @@
             int mod = meth.getModifiers();
             if (testBit(signature, index)) {
                 override(className, meth, prefix, index,
-                         keyToDesc(key, meth), cf, cp);
+                         keyToDesc(key, meth), cf, cp, forwarders);
             }
             index++;
         }
@@ -947,7 +993,7 @@
     }
 
     private void override(String thisClassname, Method meth, String prefix,
-                          int index, String desc, ClassFile cf, ConstPool cp)
+                          int index, String desc, ClassFile cf, ConstPool cp, ArrayList forwarders)
         throws CannotCompileException
     {
         Class declClass = meth.getDeclaringClass();
@@ -964,7 +1010,7 @@
 
         MethodInfo forwarder
             = makeForwarder(thisClassname, meth, desc, cp, declClass,
-                            delegatorName, index);
+                            delegatorName, index, forwarders);
         cf.addMethod(forwarder);
     }
 
@@ -1154,7 +1200,8 @@
      */
     private static MethodInfo makeForwarder(String thisClassName,
                     Method meth, String desc, ConstPool cp,
-                    Class declClass, String delegatorName, int index) {
+                    Class declClass, String delegatorName, int index,
+                    ArrayList forwarders) {
         MethodInfo forwarder = new MethodInfo(cp, meth.getName(), desc);
         forwarder.setAccessFlags(Modifier.FINAL
                     | (meth.getModifiers() & ~(Modifier.ABSTRACT
@@ -1164,13 +1211,14 @@
         int args = Descriptor.paramSize(desc);
         Bytecode code = new Bytecode(cp, 0, args + 2);
         /*
-         * if (methods[index * 2] == null) {
+         * static {
          *   methods[index * 2]
          *     = RuntimeSupport.findSuperMethod(this, <overridden name>, <desc>);
          *   methods[index * 2 + 1]
          *     = RuntimeSupport.findMethod(this, <delegator name>, <desc>);
          *     or = null // the original method is abstract.
          * }
+         *     :
          * return ($r)handler.invoke(this, methods[index * 2],
          *                methods[index * 2 + 1], $args);
          */
@@ -1180,7 +1228,7 @@
         code.addGetstatic(thisClassName, HOLDER, HOLDER_TYPE);
         code.addAstore(arrayVar);
 
-        callFind2Methods(code, meth.getName(), delegatorName, origIndex, desc, arrayVar);
+        forwarders.add(new Find2MethodsArgs(meth.getName(), delegatorName, desc, origIndex));
 
         code.addAload(0);
         code.addGetfield(thisClassName, HANDLER, HANDLER_TYPE);
@@ -1207,6 +1255,18 @@
         return forwarder;
     }
 
+    static class Find2MethodsArgs {
+        String methodName, delegatorName, descriptor;
+        int origIndex;
+
+        Find2MethodsArgs(String mname, String dname, String desc, int index) {
+            methodName = mname;
+            delegatorName = dname;
+            descriptor = desc;
+            origIndex = index;
+        }
+    }
+
     private static void setThrows(MethodInfo minfo, ConstPool cp, Method orig) {
         Class[] exceptions = orig.getExceptionTypes();
         setThrows(minfo, cp, exceptions);
@@ -1313,28 +1373,6 @@
         return regno + FactoryHelper.dataSize[index];
     }
 
-    /**
-     * @param thisMethod        might be null.
-     */
-    private static void callFind2Methods(Bytecode code, String superMethod, String thisMethod,
-                                         int index, String desc, int arrayVar) {
-        String findClass = RuntimeSupport.class.getName();
-        String findDesc
-            = "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V";
-
-        code.addAload(0);
-        code.addLdc(superMethod);
-        if (thisMethod == null)
-            code.addOpcode(Opcode.ACONST_NULL);
-        else
-            code.addLdc(thisMethod);
-
-        code.addIconst(index);
-        code.addLdc(desc);
-        code.addAload(arrayVar);
-        code.addInvokestatic(findClass, "find2Methods", findDesc);
-    }
-
     private static void addUnwrapper(Bytecode code, Class type) {
         if (type.isPrimitive()) {
             if (type == Void.TYPE)

Modified: trunk/src/main/javassist/util/proxy/RuntimeSupport.java
===================================================================
--- trunk/src/main/javassist/util/proxy/RuntimeSupport.java	2012-10-20 10:57:51 UTC (rev 675)
+++ trunk/src/main/javassist/util/proxy/RuntimeSupport.java	2012-10-25 16:38:40 UTC (rev 676)
@@ -46,24 +46,13 @@
      * @throws RuntimeException     if the methods are not found.
      * @see javassist.util.proxy.ProxyFactory
      */
-    public static void find2Methods(Object self, String superMethod,
+    public static void find2Methods(Class clazz, String superMethod,
                                     String thisMethod, int index,
                                     String desc, java.lang.reflect.Method[] methods)
     {
-        /* Once methods[index] and methods[index + 1] are set to non-null, 
-         * then their values never change.
-         */
-        if (methods[index] == null || methods[index + 1] == null) {
-            Method m1 = thisMethod == null ? null
-                                           : findMethod(self, thisMethod, desc);
-            Method m0 = findSuperMethod(self, superMethod, desc);
-            synchronized (methods) {
-                if (methods[index] == null) {
-                    methods[index + 1] = m1;
-                    methods[index] = m0;
-                }
-            }
-        }
+        methods[index + 1] = thisMethod == null ? null
+                                                : findMethod(clazz, thisMethod, desc);
+        methods[index] = findSuperMethod(clazz, superMethod, desc);
     }
 
     /**
@@ -72,10 +61,10 @@
      *
      * @throws RuntimeException     if the method is not found.
      */
-    public static Method findMethod(Object self, String name, String desc) {
-        Method m = findMethod2(self.getClass(), name, desc);
+    public static Method findMethod(Class clazz, String name, String desc) {
+        Method m = findMethod2(clazz, name, desc);
         if (m == null)
-            error(self, name, desc);
+            error(clazz, name, desc);
 
         return m;
     }
@@ -86,21 +75,20 @@
      *
      * @throws RuntimeException     if the method is not found.
      */
-    public static Method findSuperMethod(Object self, String name, String desc) {
-        Class clazz = self.getClass();
+    public static Method findSuperMethod(Class clazz, String name, String desc) {
         Method m = findSuperMethod2(clazz.getSuperclass(), name, desc);
         if (m == null)
             m = searchInterfaces(clazz, name, desc);
 
         if (m == null)
-            error(self, name, desc);
+            error(clazz, name, desc);
 
         return m;
     }
 
-    private static void error(Object self, String name, String desc) {
+    private static void error(Class clazz, String name, String desc) {
         throw new RuntimeException("not found " + name + ":" + desc
-                + " in " + self.getClass().getName());
+                + " in " + clazz.getName());
     }
 
     private static Method findSuperMethod2(Class clazz, String name, String desc) {

Modified: trunk/src/test/javassist/JvstTest.java
===================================================================
--- trunk/src/test/javassist/JvstTest.java	2012-10-20 10:57:51 UTC (rev 675)
+++ trunk/src/test/javassist/JvstTest.java	2012-10-25 16:38:40 UTC (rev 676)
@@ -1116,14 +1116,14 @@
         suite.addTestSuite(javassist.bytecode.InsertGap0.class);
         suite.addTestSuite(javassist.tools.reflect.LoaderTest.class);
         suite.addTestSuite(testproxy.ProxyTester.class);
-        // suite.addTestSuite(testproxy.ProxyFactoryPerformanceTest.class);
+        suite.addTestSuite(testproxy.ProxyFactoryPerformanceTest.class); // remove?
         suite.addTestSuite(javassist.proxyfactory.ProxyFactoryTest.class);
         suite.addTestSuite(javassist.proxyfactory.Tester.class);
         suite.addTestSuite(test.javassist.proxy.ProxySerializationTest.class);
         suite.addTestSuite(test.javassist.convert.ArrayAccessReplaceTest.class);
         suite.addTestSuite(test.javassist.proxy.JASSIST113RegressionTest.class);
         suite.addTestSuite(test.javassist.proxy.JBPAPP9257Test.class);
-        //suite.addTestSuite(test.javassist.proxy.ProxyCacheGCTest.class);
+        suite.addTestSuite(test.javassist.proxy.ProxyCacheGCTest.class);  // remvoe?
         suite.addTestSuite(test.javassist.proxy.ProxyFactoryCompatibilityTest.class);
         suite.addTestSuite(test.javassist.proxy.ProxySerializationTest.class);
         suite.addTestSuite(test.javassist.proxy.ProxySimpleTest.class);

Modified: trunk/src/test/javassist/proxyfactory/ProxyFactoryTest.java
===================================================================
--- trunk/src/test/javassist/proxyfactory/ProxyFactoryTest.java	2012-10-20 10:57:51 UTC (rev 675)
+++ trunk/src/test/javassist/proxyfactory/ProxyFactoryTest.java	2012-10-25 16:38:40 UTC (rev 676)
@@ -12,8 +12,6 @@
  * <a href="mailto:struberg at yahoo.de">Mark Struberg</a>
  */
 public class ProxyFactoryTest extends TestCase {
-
-
     public void testMethodHandlers() throws Exception {
         ProxyFactory fact = new ProxyFactory();
         fact.setSuperclass(MyCls.class);

Modified: trunk/src/test/test/javassist/proxy/ProxySimpleTest.java
===================================================================
--- trunk/src/test/test/javassist/proxy/ProxySimpleTest.java	2012-10-20 10:57:51 UTC (rev 675)
+++ trunk/src/test/test/javassist/proxy/ProxySimpleTest.java	2012-10-25 16:38:40 UTC (rev 676)
@@ -9,9 +9,47 @@
 import java.io.Serializable;
 import java.lang.reflect.Method;
 
+import javassist.util.proxy.MethodFilter;
+import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.Proxy;
 import javassist.util.proxy.ProxyFactory;
 
 public class ProxySimpleTest extends TestCase {
+
+    String testResult;
+
+    public void testProxyFactory() throws Exception {
+        ProxyFactory f = new ProxyFactory();
+        f.writeDirectory = "./proxy";
+        f.setSuperclass(Foo.class);
+        f.setFilter(new MethodFilter() {
+            public boolean isHandled(Method m) {
+                return m.getName().startsWith("f");
+            }
+        });
+        Class c = f.createClass();
+        MethodHandler mi = new MethodHandler() {
+            public Object invoke(Object self, Method m, Method proceed,
+                                 Object[] args) throws Throwable {
+                testResult += args[0].toString();
+                return proceed.invoke(self, args);  // execute the original method.
+            }
+        };
+        Foo foo = (Foo)c.newInstance();
+        ((Proxy)foo).setHandler(mi);
+        testResult = "";
+        foo.foo(1);
+        foo.foo2(2);
+        foo.bar(3);
+        assertEquals("12", testResult);
+    }
+
+    public static class Foo {
+        public int foo(int i) { return i + 1; }
+        public int foo2(int i) { return i + 2; }
+        public int bar(int i) { return i + 1; }
+    }
+
     public void testReadWrite() throws Exception {
         final String fileName = "read-write.bin";
         ProxyFactory.ClassLoaderProvider cp = ProxyFactory.classLoaderProvider;



More information about the jboss-cvs-commits mailing list