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
+ {
+
+ }
+}