You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by db...@apache.org on 2012/09/15 06:50:28 UTC

svn commit: r1385011 - in /openwebbeans/trunk/webbeans-impl/src: main/java/org/apache/webbeans/decorator/ main/java/org/apache/webbeans/proxy/ main/java/org/apache/webbeans/proxy/asm/ test/java/org/apache/webbeans/proxy/ test/java/org/apache/webbeans/p...

Author: dblevins
Date: Sat Sep 15 04:50:27 2012
New Revision: 1385011

URL: http://svn.apache.org/viewvc?rev=1385011&view=rev
Log:
OWB-701: Remove Javassist
Mostly functional ASM Proxy impl.  Just Abstract Decorators not working

Added:
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/proxy/
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/proxy/asm/
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/proxy/asm/AsmProxyFactoryTest.java
Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/AbstractDecoratorMethodHandler.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmFactory.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmProxyFactory.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/AbstractDecoratorMethodHandler.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/AbstractDecoratorMethodHandler.java?rev=1385011&r1=1385010&r2=1385011&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/AbstractDecoratorMethodHandler.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/AbstractDecoratorMethodHandler.java Sat Sep 15 04:50:27 2012
@@ -24,8 +24,6 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.lang.reflect.Method;
 
-import javax.naming.OperationNotSupportedException;
-
 import org.apache.webbeans.proxy.MethodHandler;
 
 public class AbstractDecoratorMethodHandler implements MethodHandler, Serializable
@@ -35,13 +33,13 @@ public class AbstractDecoratorMethodHand
 
     public AbstractDecoratorMethodHandler()
     {
-        new Exception().fillInStackTrace().printStackTrace();
+//        new Exception().fillInStackTrace().printStackTrace();
     }
 
     public Object invoke(Object proxy, Method method, Object[] args)
         throws Throwable
     {
-        throw new OperationNotSupportedException();
+        throw new NoSuchMethodException();
     }
 
     public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java?rev=1385011&r1=1385010&r2=1385011&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java Sat Sep 15 04:50:27 2012
@@ -66,6 +66,7 @@ public final class JavassistProxyFactory
     // second level map is indexed on local interface
     private ConcurrentMap<OwbBean<?>, ConcurrentMap<Class<?>, Class<?>>> ejbProxyClasses = new ConcurrentHashMap<OwbBean<?>, ConcurrentMap<Class<?>, Class<?>>>();
     private Factory factory = new JavassistFactory();
+//    private Factory factory = new AsmFactory();
 
     /**
      * This map contains all configured special Scope->InterceptorHandler mappings.
@@ -184,7 +185,7 @@ public final class JavassistProxyFactory
     private Object createProxy(Class<?> proxyClass)
         throws InstantiationException, IllegalAccessException
     {
-        return proxyClass.newInstance();
+        return factory.createProxy(proxyClass);
     }
 
     private InterceptorHandler createInterceptorHandler(OwbBean<?> bean, CreationalContext<?> creationalContext)

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmFactory.java?rev=1385011&r1=1385010&r2=1385011&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmFactory.java Sat Sep 15 04:50:27 2012
@@ -18,8 +18,6 @@
  */
 package org.apache.webbeans.proxy.asm;
 
-import java.lang.reflect.Proxy;
-
 import org.apache.webbeans.proxy.Factory;
 import org.apache.webbeans.proxy.MethodHandler;
 import org.apache.webbeans.util.WebBeansUtil;
@@ -27,52 +25,40 @@ import org.apache.webbeans.util.WebBeans
 /**
  * @version $Rev$ $Date$
  */
-public class AsmFactory implements Factory
+public class AsmFactory
+    implements Factory
 {
 
     public Object createProxy(MethodHandler handler, Class<?> superClass, Class<?>[] interfaceArray)
     {
-        if (useJdkProxy(superClass))
-        {
-            return Proxy.newProxyInstance(WebBeansUtil.getCurrentClassLoader(), interfaceArray, handler);
-        }
-        else
-        {
-            return AsmProxyFactory.newProxyInstance(WebBeansUtil.getCurrentClassLoader(), handler, superClass,
-                                                    interfaceArray);
-        }
-
+        return AsmProxyFactory.newProxyInstance(WebBeansUtil.getCurrentClassLoader(), handler, superClass,
+                                                interfaceArray);
     }
 
     public Class<?> getProxyClass(Class<?> superClass, Class<?>[] interfaces)
     {
-        return null;
+        return AsmProxyFactory.getProxyClass(WebBeansUtil.getCurrentClassLoader(), superClass, interfaces);
     }
 
     public boolean isProxyInstance(Object o)
     {
-        return false;
+        return AsmProxyFactory.isProxyClass(o.getClass());
     }
 
     public Object createProxy(MethodHandler handler, Class<?>[] interfaces)
         throws InstantiationException, IllegalAccessException
     {
-        return null;
+        return createProxy(handler, null, interfaces);
     }
 
     public Object createProxy(Class<?> proxyClass)
         throws InstantiationException, IllegalAccessException
     {
-        return null;
+        return AsmProxyFactory.constructProxy(proxyClass, null);
     }
 
     public void setHandler(Object proxy, MethodHandler handler)
     {
+        AsmProxyFactory.setInvocationHandler(proxy, handler);
     }
-
-    private boolean useJdkProxy(Class<?> superClass)
-    {
-        return superClass == null || superClass.equals(Object.class);
-    }
-
 }

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmProxyFactory.java?rev=1385011&r1=1385010&r2=1385011&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/asm/AsmProxyFactory.java Sat Sep 15 04:50:27 2012
@@ -25,6 +25,7 @@ import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
@@ -38,6 +39,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.webbeans.proxy.ProxyGenerationException;
 import org.objectweb.asm.ClassWriter;
@@ -50,6 +52,8 @@ public class AsmProxyFactory
     implements Opcodes
 {
 
+    private static final AtomicInteger ID = new AtomicInteger(1);
+
     public static final InvocationHandler NON_BUSINESS_HANDLER = new NonBusinessHandler();
 
     private static final String BUSSINESS_HANDLER_NAME = "businessHandler";
@@ -66,7 +70,7 @@ public class AsmProxyFactory
         try
         {
 
-            final Class proxyClass = GENERATOR.createProxy(classToSubclass, classLoader, interfaces);
+            final Class proxyClass = GENERATOR.getProxyClass(classLoader, classToSubclass, interfaces);
             final Object object = GENERATOR.constructProxy(proxyClass, handler);
 
             return object;
@@ -109,9 +113,38 @@ public class AsmProxyFactory
         }
     }
 
-    public Object constructProxy(final Class clazz, final InvocationHandler handler)
+    public static void setInvocationHandler(Object proxy, InvocationHandler invocationHandler)
+    {
+        try
+        {
+            final Field field = proxy.getClass().getDeclaredField(BUSSINESS_HANDLER_NAME);
+            field.setAccessible(true);
+            try
+            {
+                field.set(proxy, invocationHandler);
+            }
+            finally
+            {
+                field.setAccessible(false);
+            }
+        }
+        catch (NoSuchFieldException e)
+        {
+            throw new IllegalArgumentException(e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    public static Object constructProxy(final Class clazz, InvocationHandler handler)
         throws IllegalStateException
     {
+        if (handler == null)
+        {
+            handler = new NoHandler();
+        }
 
         final Object instance = Unsafe.allocateInstance(clazz);
 
@@ -121,6 +154,17 @@ public class AsmProxyFactory
         return instance;
     }
 
+    private static class NoHandler
+        implements InvocationHandler
+    {
+        public Object invoke(Object proxy, Method method, Object[] args)
+            throws Throwable
+        {
+            throw new UnsupportedOperationException("No valid MethodHandler has been set");
+        }
+    }
+
+
     private static Field getDeclaredField(final Class clazz, final String fieldName)
     {
         try
@@ -135,14 +179,23 @@ public class AsmProxyFactory
         }
     }
 
-    public static boolean isProxy(final Class<?> clazz)
+    public static boolean isProxyClass(final Class<?> clazz)
     {
         return clazz.isAnnotationPresent(Proxy.class);
     }
 
-    public Class createProxy(final Class<?> classToProxy, final ClassLoader cl, final Class... interfaces)
+    public static Class getProxyClass(final ClassLoader cl, final Class<?> classToProxy, final Class... interfaces)
     {
-        final String proxyName = classToProxy.getName() + "$LocalBeanProxy";
+        final String proxyName;
+        if (classToProxy == null || classToProxy.getName().startsWith("java.") ||
+            classToProxy.getName().startsWith("javax."))
+        {
+            proxyName = "BeanProxy$" + ID.incrementAndGet();
+        }
+        else
+        {
+            proxyName = classToProxy.getName() + "$BeanProxy";
+        }
         final String classFileName = proxyName.replace('.', '/');
 
         try
@@ -165,7 +218,7 @@ public class AsmProxyFactory
             try
             {
                 final byte[] proxyBytes = generateProxy(classToProxy, classFileName, interfaces);
-                return Unsafe.defineClass(classToProxy, proxyName, proxyBytes);
+                return Unsafe.defineClass(proxyName, proxyBytes, cl, null);
             }
             catch (Exception e)
             {
@@ -176,7 +229,8 @@ public class AsmProxyFactory
         }
     }
 
-    private byte[] generateProxy(final Class<?> classToProxy, final String proxyName, final Class<?>... interfaces)
+    private static byte[] generateProxy(final Class<?> classToProxy, final String proxyName,
+                                        final Class<?>... interfaces)
         throws ProxyGenerationException
     {
         final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
@@ -203,6 +257,28 @@ public class AsmProxyFactory
         cw.visitField(ACC_FINAL + ACC_PRIVATE, NON_BUSINESS_HANDLER_NAME, "Ljava/lang/reflect/InvocationHandler;", null,
                       null).visitEnd();
 
+        for (Constructor<?> constructor : classToProxy.getDeclaredConstructors())
+        {
+
+            final String descriptor = Type.getConstructorDescriptor(constructor);
+            final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", descriptor, null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+
+            int offset = 1;
+            for (Class<?> aClass : constructor.getParameterTypes())
+            {
+                final Type type = Type.getType(aClass);
+                mv.visitVarInsn(type.getOpcode(ILOAD), offset);
+                offset += type.getSize();
+            }
+
+            mv.visitMethodInsn(INVOKESPECIAL, classFileName, "<init>", descriptor);
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(-1, -1);
+            mv.visitEnd();
+
+        }
         final Map<String, List<Method>> methodMap = new HashMap<String, List<Method>>();
 
         getNonPrivateMethods(classToProxy, methodMap);
@@ -238,7 +314,7 @@ public class AsmProxyFactory
         return cw.toByteArray();
     }
 
-    private void getNonPrivateMethods(Class<?> clazz, Map<String, List<Method>> methodMap)
+    private static void getNonPrivateMethods(Class<?> clazz, Map<String, List<Method>> methodMap)
     {
         while (clazz != null)
         {
@@ -276,7 +352,7 @@ public class AsmProxyFactory
         }
     }
 
-    private boolean isOverridden(final List<Method> methods, final Method method)
+    private static boolean isOverridden(final List<Method> methods, final Method method)
     {
         for (final Method m : methods)
         {
@@ -289,8 +365,8 @@ public class AsmProxyFactory
     }
 
 
-    private void processMethod(final ClassWriter cw, final Method method, final String proxyName,
-                               final String handlerName)
+    private static void processMethod(final ClassWriter cw, final Method method, final String proxyName,
+                                      final String handlerName)
         throws ProxyGenerationException
     {
         if ("<init>".equals(method.getName()))
@@ -526,7 +602,7 @@ public class AsmProxyFactory
      * @param type Type the needs to be returned
      * @return The matching bytecode instruction
      */
-    private int getReturnInsn(final Class<?> type)
+    private static int getReturnInsn(final Class<?> type)
     {
         if (type.isPrimitive())
         {
@@ -574,7 +650,7 @@ public class AsmProxyFactory
      * @param type Type to load
      * @return Bytecode instruction to use
      */
-    private int getVarInsn(final Class<?> type)
+    private static int getVarInsn(final Class<?> type)
     {
         if (type.isPrimitive())
         {
@@ -621,7 +697,7 @@ public class AsmProxyFactory
      * @param type Type whose primitive method we want to lookup
      * @return The name of the method to use
      */
-    private String getPrimitiveMethod(final Class<?> type)
+    private static String getPrimitiveMethod(final Class<?> type)
     {
         if (Integer.TYPE.equals(type))
         {
@@ -665,7 +741,7 @@ public class AsmProxyFactory
      * @param returnType The type to cast to with CHECKCAST
      * @return CHECKCAST parameter
      */
-    String getCastType(final Class<?> returnType)
+    static String getCastType(final Class<?> returnType)
     {
         if (returnType.isPrimitive())
         {
@@ -683,7 +759,7 @@ public class AsmProxyFactory
      * @param type
      * @return
      */
-    private String getWrapperType(final Class<?> type)
+    private static String getWrapperType(final Class<?> type)
     {
         if (Integer.TYPE.equals(type))
         {
@@ -731,7 +807,7 @@ public class AsmProxyFactory
      * @param mv
      * @param i
      */
-    private void pushIntOntoStack(final MethodVisitor mv, final int i)
+    private static void pushIntOntoStack(final MethodVisitor mv, final int i)
     {
         if (i == 0)
         {
@@ -776,7 +852,7 @@ public class AsmProxyFactory
      * @param type Type of array to create
      * @throws ProxyGenerationException
      */
-    private void createArrayDefinition(final MethodVisitor mv, final int size, final Class<?> type)
+    private static void createArrayDefinition(final MethodVisitor mv, final int size, final Class<?> type)
         throws ProxyGenerationException
     {
         // create a new array of java.lang.class (2)
@@ -792,7 +868,7 @@ public class AsmProxyFactory
     }
 
 
-    String getMethodSignatureAsString(final Class<?> returnType, final Class<?>[] parameterTypes)
+    static String getMethodSignatureAsString(final Class<?> returnType, final Class<?>[] parameterTypes)
     {
         final StringBuilder builder = new StringBuilder();
         builder.append("(");
@@ -813,7 +889,7 @@ public class AsmProxyFactory
      * @param type
      * @return
      */
-    private String getPrimitiveLetter(final Class<?> type)
+    private static String getPrimitiveLetter(final Class<?> type)
     {
         if (Integer.TYPE.equals(type))
         {
@@ -862,7 +938,7 @@ public class AsmProxyFactory
      * @param wrap          True if a non-array object should be wrapped with L and ; - e.g. Ljava/lang/Integer;
      * @return String to use for ASM
      */
-    public String getAsmTypeAsString(final Class<?> parameterType, final boolean wrap)
+    public static String getAsmTypeAsString(final Class<?> parameterType, final boolean wrap)
     {
         if (parameterType.isArray())
         {
@@ -1092,12 +1168,11 @@ public class AsmProxyFactory
             }
         }
 
-        private static Class defineClass(Class<?> clsToProxy, String proxyName, byte[] proxyBytes)
+        private static Class defineClass(String proxyName, byte[] proxyBytes, final ClassLoader classLoader,
+                                         ProtectionDomain o)
             throws IllegalAccessException, InvocationTargetException
         {
-            final ProtectionDomain protectionDomain = clsToProxy.getProtectionDomain();
-            return (Class<?>) DEFINE_CLASS.invoke(UNSAFE, proxyName, proxyBytes, 0, proxyBytes.length,
-                                                 clsToProxy.getClassLoader(), protectionDomain);
+            return (Class<?>) DEFINE_CLASS.invoke(UNSAFE, proxyName, proxyBytes, 0, proxyBytes.length, classLoader, o);
         }
     }
 

Added: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/proxy/asm/AsmProxyFactoryTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/proxy/asm/AsmProxyFactoryTest.java?rev=1385011&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/proxy/asm/AsmProxyFactoryTest.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/proxy/asm/AsmProxyFactoryTest.java Sat Sep 15 04:50:27 2012
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.webbeans.proxy.asm;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AsmProxyFactoryTest
+    extends TestCase
+{
+    public void testGetProxyClass()
+        throws Exception
+    {
+        final ClassLoader classLoader = this.getClass().getClassLoader();
+        final Class proxyClass = AsmProxyFactory.getProxyClass(classLoader, Foo.class);
+
+        proxyClass.getDeclaredConstructor();
+        proxyClass.getDeclaredConstructor(File.class);
+    }
+
+
+    public static class Foo
+    {
+        private final File file;
+
+        public Foo(File file)
+        {
+            this.file = file;
+        }
+
+        public Foo()
+        {
+            this.file = null;
+        }
+    }
+
+    public static class Bar extends Foo
+    {
+        public Bar(File file)
+        {
+            super(file);
+        }
+
+        public Bar()
+        {
+        }
+    }
+
+    public static abstract class Baz extends Bar
+    {
+
+    }
+}