Author: dblevins
Date: Fri Aug 10 07:15:53 2012
New Revision: 1371584

URL: http://svn.apache.org/viewvc?rev=1371584&view=rev
Log:
Small refactoring and code cleanup
OPENEJB-1885 Simply EJB Proxy Code

Modified:
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java

Modified: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java?rev=1371584&r1=1371583&r2=1371584&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyGeneratorImpl.java
 Fri Aug 10 07:15:53 2012
@@ -17,7 +17,6 @@
 package org.apache.openejb.util.proxy;
 
 import org.apache.xbean.asm.ClassWriter;
-import org.apache.xbean.asm.FieldVisitor;
 import org.apache.xbean.asm.Label;
 import org.apache.xbean.asm.MethodVisitor;
 import org.apache.xbean.asm.Opcodes;
@@ -45,102 +44,17 @@ public class LocalBeanProxyGeneratorImpl
     static final String BUSSINESS_HANDLER_NAME = "businessHandler";
     static final String NON_BUSINESS_HANDLER_NAME = "nonBusinessHandler";
 
-    // sun.misc.Unsafe
-    private static final Object unsafe;
-    private static final Method defineClass;
-    private static final Method allocateInstance;
-    private static final Method putObject;
-    private static final Method objectFieldOffset;
+    public Object constructProxy(final Class clazz, final 
java.lang.reflect.InvocationHandler handler) throws IllegalStateException {
 
+        final Object instance = Unsafe.allocateInstance(clazz);
 
-    static {
-        final Class<?> unsafeClass;
-        try {
-            unsafeClass = AccessController.doPrivileged(new 
PrivilegedAction<Class<?>>() {
-                public Class<?> run() {
-                    try {
-                        return 
Thread.currentThread().getContextClassLoader().loadClass("sun.misc.Unsafe");
-                    } catch (Exception e) {
-                        try {
-                            return 
ClassLoader.getSystemClassLoader().loadClass("sun.misc.Unsafe");
-                        } catch (ClassNotFoundException e1) {
-                            throw new IllegalStateException("Cannot get 
sun.misc.Unsafe", e);
-                        }
-                    }
-                }
-            });
-        } catch (Exception e) {
-            throw new IllegalStateException("Cannot get sun.misc.Unsafe 
class", e);
-        }
-
-        unsafe = AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
-                try {
-                    Field field = unsafeClass.getDeclaredField("theUnsafe");
-                    field.setAccessible(true);
-                    return field.get(null);
-                } catch (Exception e) {
-                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe", e);
-                }
-            }
-        });
-        allocateInstance = AccessController.doPrivileged(new 
PrivilegedAction<Method>() {
-            public Method run() {
-                try {
-                    Method mtd = 
unsafeClass.getDeclaredMethod("allocateInstance", Class.class);
-                    mtd.setAccessible(true);
-                    return mtd;
-                } catch (Exception e) {
-                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe.allocateInstance", e);
-                }
-            }
-        });
-        objectFieldOffset = AccessController.doPrivileged(new 
PrivilegedAction<Method>() {
-            public Method run() {
-                try {
-                    Method mtd = 
unsafeClass.getDeclaredMethod("objectFieldOffset", Field.class);
-                    mtd.setAccessible(true);
-                    return mtd;
-                } catch (Exception e) {
-                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe.objectFieldOffset", e);
-                }
-            }
-        });
-        putObject = AccessController.doPrivileged(new 
PrivilegedAction<Method>() {
-            public Method run() {
-                try {
-                    Method mtd = unsafeClass.getDeclaredMethod("putObject", 
Object.class, long.class, Object.class);
-                    mtd.setAccessible(true);
-                    return mtd;
-                } catch (Exception e) {
-                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe.putObject", e);
-                }
-            }
-        });
-        defineClass = AccessController.doPrivileged(new 
PrivilegedAction<Method>() {
-            public Method run() {
-                try {
-                    Method mtd = unsafeClass.getDeclaredMethod("defineClass", 
String.class, byte[].class, int.class, int.class, ClassLoader.class, 
ProtectionDomain.class);
-                    mtd.setAccessible(true);
-                    return mtd;
-                } catch (Exception e) {
-                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe.defineClass", e);
-                }
-            }
-        });
-    }
-
-    public Object constructProxy(Class clazz, 
java.lang.reflect.InvocationHandler handler) throws IllegalStateException {
-
-        final Object instance = allocateInstance(clazz);
-
-        setValue(getDeclaredField(clazz, BUSSINESS_HANDLER_NAME), instance, 
handler);
-        setValue(getDeclaredField(clazz, NON_BUSINESS_HANDLER_NAME), instance, 
NON_BUSINESS_HANDLER);
+        Unsafe.setValue(getDeclaredField(clazz, BUSSINESS_HANDLER_NAME), 
instance, handler);
+        Unsafe.setValue(getDeclaredField(clazz, NON_BUSINESS_HANDLER_NAME), 
instance, NON_BUSINESS_HANDLER);
 
         return instance;
     }
 
-    private Field getDeclaredField(Class clazz, final String fieldName) {
+    private static Field getDeclaredField(final Class clazz, final String 
fieldName) {
         try {
             return clazz.getDeclaredField(fieldName);
         } catch (NoSuchFieldException e) {
@@ -149,52 +63,24 @@ public class LocalBeanProxyGeneratorImpl
         }
     }
 
-    private Object allocateInstance(Class clazz) {
-        final Object instance;
-        try {
-            instance = allocateInstance.invoke(unsafe, clazz);
-        } catch (IllegalAccessException e) {
-            throw new IllegalStateException("Failed to allocateInstance of 
Proxy class " + clazz.getName(), e);
-        } catch (InvocationTargetException e) {
-            Throwable throwable = e.getTargetException() != null ? 
e.getTargetException() : e;
-            throw new IllegalStateException("Failed to allocateInstance of 
Proxy class " + clazz.getName(), throwable);
-        }
-        return instance;
-    }
-
-    private void setValue(Field field, Object object, Object value) {
-        long offset;
-        try {
-            offset = (Long) objectFieldOffset.invoke(unsafe, field);
-        } catch (Exception e) {
-            throw new IllegalStateException("Failed getting offset for: 
field=" + field.getName() + "  class=" + field.getDeclaringClass().getName(), 
e);
-        }
-
-        try {
-            putObject.invoke(unsafe, object, offset, value);
-        } catch (Exception e) {
-            throw new IllegalStateException("Failed putting field=" + 
field.getName() + "  class=" + field.getDeclaringClass().getName(), e);
-        }
-    }
-
-    public Class createProxy(Class<?> clsToProxy, ClassLoader cl) {
-        String proxyName = generateProxyName(clsToProxy.getName());
+    public Class createProxy(final Class<?> clsToProxy, final ClassLoader cl) {
+        final String proxyName = generateProxyName(clsToProxy.getName());
         return createProxy(clsToProxy, proxyName, cl);
     }
 
-    private static String generateProxyName(String clsName) {
+    private static String generateProxyName(final String clsName) {
         return clsName + "$LocalBeanProxy";
     }
 
-    public static boolean isLocalBean(Class<?> clazz) {
+    public static boolean isLocalBean(final Class<?> clazz) {
         if (clazz.getSuperclass() == null) {
             return false;
         }
         return 
clazz.getName().equals(LocalBeanProxyGeneratorImpl.generateProxyName(clazz.getSuperclass().getName()));
     }
 
-    private Class createProxy(Class<?> clsToProxy, String proxyName, 
ClassLoader cl) {
-        String clsName = proxyName.replaceAll("\\.", "/");
+    private Class createProxy(final Class<?> clsToProxy, final String 
proxyName, final ClassLoader cl) {
+        final String clsName = proxyName.replace('.', '/');
 
         try {
             return cl.loadClass(proxyName);
@@ -208,47 +94,45 @@ public class LocalBeanProxyGeneratorImpl
             }
 
             try {
-                byte[] proxyBytes = generateProxy(clsToProxy, clsName);
-                return (Class<?>) defineClass.invoke(unsafe, proxyName, 
proxyBytes, 0, proxyBytes.length, clsToProxy.getClassLoader(), 
clsToProxy.getProtectionDomain());
+                final byte[] proxyBytes = generateProxy(clsToProxy, clsName);
+                return Unsafe.defineClass(clsToProxy, proxyName, proxyBytes);
             } catch (Exception e) {
                 throw new InternalError(e.toString());
             }
         }
     }
 
-    private byte[] generateProxy(Class<?> clsToProxy, String proxyName) throws 
ProxyGenerationException {
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-        FieldVisitor fv;
-        MethodVisitor mv;
+    private byte[] generateProxy(final Class<?> classToProxy, final String 
proxyName) throws ProxyGenerationException {
+        final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
 
-        String clsToOverride = clsToProxy.getName().replaceAll("\\.", "/");
-        String proxyClassName = proxyName.replaceAll("\\.", "/");
+        final String proxyClassFileName = proxyName.replace('.', '/');
+        final String classFileName = classToProxy.getName().replace('.', '/');
 
         // push class signature
-        cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, proxyClassName, null, 
clsToOverride, SERIALIZABLE);
-        cw.visitSource(clsToOverride + ".java", null);
+        cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, proxyClassFileName, null, 
classFileName, SERIALIZABLE);
+        cw.visitSource(classFileName + ".java", null);
 
         // push InvocationHandler fields
-        fv = cw.visitField(ACC_FINAL + ACC_PRIVATE, BUSSINESS_HANDLER_NAME, 
"Ljava/lang/reflect/InvocationHandler;", null, null);
-        fv.visitEnd();
-        fv = cw.visitField(ACC_FINAL + ACC_PRIVATE, NON_BUSINESS_HANDLER_NAME, 
"Ljava/lang/reflect/InvocationHandler;", null, null);
-        fv.visitEnd();
-
-        Map<String, List<Method>> methodMap = getNonPrivateMethods(new 
Class[]{clsToProxy});
-
-        for (Map.Entry<String, List<Method>> entry : methodMap.entrySet()) {
-            for (Method method : entry.getValue()) {
-                String name = method.getName();
-                int modifiers = method.getModifiers();
-                if (Modifier.isPublic(modifiers) ||
-                        (method.getParameterTypes().length == 0 &&
-                                ("finalize".equals(name) || 
"clone".equals(name)))) {
+        cw.visitField(ACC_FINAL + ACC_PRIVATE, BUSSINESS_HANDLER_NAME, 
"Ljava/lang/reflect/InvocationHandler;", null, null).visitEnd();
+        cw.visitField(ACC_FINAL + ACC_PRIVATE, NON_BUSINESS_HANDLER_NAME, 
"Ljava/lang/reflect/InvocationHandler;", null, null).visitEnd();
+
+        final Map<String, List<Method>> methodMap = 
getNonPrivateMethods(classToProxy);
+
+        // Iterate over the public methods
+        for (final Map.Entry<String, List<Method>> entry : 
methodMap.entrySet()) {
+
+            for (final Method method : entry.getValue()) {
+                final String name = method.getName();
+
+                if (Modifier.isPublic(method.getModifiers())
+                        || (method.getParameterTypes().length == 0 && 
("finalize".equals(name)
+                        || "clone".equals(name)))) {
                     // forward invocations of any public methods or 
                     // finalize/clone methods to businessHandler 
-                    processMethod(cw, method, proxyClassName, 
BUSSINESS_HANDLER_NAME);
+                    processMethod(cw, method, proxyClassFileName, 
BUSSINESS_HANDLER_NAME);
                 } else {
                     // forward invocations of any other methods to 
nonBusinessHandler
-                    processMethod(cw, method, proxyClassName, 
NON_BUSINESS_HANDLER_NAME);
+                    processMethod(cw, method, proxyClassFileName, 
NON_BUSINESS_HANDLER_NAME);
                 }
             }
         }
@@ -261,44 +145,42 @@ public class LocalBeanProxyGeneratorImpl
       * that are not final or static. The returned map includes the inherited 
methods
       * and ensures that overridden methods are included once.
       */
-    private Map<String, List<Method>> getNonPrivateMethods(Class<?>[] classes) 
{
-        Map<String, List<Method>> methodMap = new HashMap<String, 
List<Method>>();
+    private Map<String, List<Method>> getNonPrivateMethods(Class<?> clazz) {
+        final Map<String, List<Method>> methodMap = new HashMap<String, 
List<Method>>();
 
-        for (int i = 0; i < classes.length; i++) {
-            Class<?> clazz = classes[i];
-
-            while (clazz != null) {
-                for (Method method : clazz.getDeclaredMethods()) {
-                    int modifiers = method.getModifiers();
-                    if (Modifier.isFinal(modifiers) ||
-                            Modifier.isPrivate(modifiers) ||
-                            Modifier.isStatic(modifiers)) {
-                        continue;
-                    }
-
-                    List<Method> methods = methodMap.get(method.getName());
-                    if (methods == null) {
-                        methods = new ArrayList<Method>();
-                        methods.add(method);
-                        methodMap.put(method.getName(), methods);
+        while (clazz != null) {
+            for (Method method : clazz.getDeclaredMethods()) {
+                final int modifiers = method.getModifiers();
+
+                if (Modifier.isFinal(modifiers)
+                        || Modifier.isPrivate(modifiers)
+                        || Modifier.isStatic(modifiers)) {
+                    continue;
+                }
+
+                List<Method> methods = methodMap.get(method.getName());
+                if (methods == null) {
+                    methods = new ArrayList<Method>();
+                    methods.add(method);
+                    methodMap.put(method.getName(), methods);
+                } else {
+                    if (isOverridden(methods, method)) {
+                        // method is overridden in superclass, so do nothing
                     } else {
-                        if (isOverridden(methods, method)) {
-                            // method is overridden in superclass, so do 
nothing
-                        } else {
-                            // method is not overridden, so add it
-                            methods.add(method);
-                        }
+                        // method is not overridden, so add it
+                        methods.add(method);
                     }
                 }
-
-                clazz = clazz.getSuperclass();
             }
+
+            clazz = clazz.getSuperclass();
         }
+
         return methodMap;
     }
 
-    private boolean isOverridden(List<Method> methods, Method method) {
-        for (Method m : methods) {
+    private boolean isOverridden(final List<Method> methods, final Method 
method) {
+        for (final Method m : methods) {
             if (Arrays.equals(m.getParameterTypes(), 
method.getParameterTypes())) {
                 return true;
             }
@@ -306,15 +188,15 @@ public class LocalBeanProxyGeneratorImpl
         return false;
     }
 
-    private void processMethod(ClassWriter cw, Method method, String 
proxyName, String handlerName) throws ProxyGenerationException {
+    private void processMethod(final ClassWriter cw, final Method method, 
final String proxyName, final String handlerName) throws 
ProxyGenerationException {
         if ("<init>".equals(method.getName())) {
             return;
         }
 
-        Class<?> returnType = method.getReturnType();
-        Class<?>[] parameterTypes = method.getParameterTypes();
-        Class<?>[] exceptionTypes = method.getExceptionTypes();
-        int modifiers = method.getModifiers();
+        final Class<?> returnType = method.getReturnType();
+        final Class<?>[] parameterTypes = method.getParameterTypes();
+        final Class<?>[] exceptionTypes = method.getExceptionTypes();
+        final int modifiers = method.getModifiers();
 
         // push the method definition
         int modifier = 0;
@@ -323,25 +205,23 @@ public class LocalBeanProxyGeneratorImpl
         } else if (Modifier.isProtected(modifiers)) {
             modifier = ACC_PROTECTED;
         }
-        MethodVisitor mv = cw.visitMethod(modifier, method.getName(), 
getMethodSignatureAsString(returnType, parameterTypes), null, null);
+
+        final MethodVisitor mv = cw.visitMethod(modifier, method.getName(), 
getMethodSignatureAsString(returnType, parameterTypes), null, null);
         mv.visitCode();
 
         // push try/catch block, to catch declared exceptions, and to catch 
java.lang.Throwable
-        Label l0 = new Label();
-        Label l1 = new Label();
-        Label l2 = new Label();
-        Label l3 = new Label();
+        final Label l0 = new Label();
+        final Label l1 = new Label();
+        final Label l2 = new Label();
 
         if (exceptionTypes.length > 0) {
             mv.visitTryCatchBlock(l0, l1, l2, 
"java/lang/reflect/InvocationTargetException");
         }
 
-//             mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable");
-
         // push try code
         mv.visitLabel(l0);
-        String clsToOverride = 
method.getDeclaringClass().getName().replaceAll("\\.", "/");
-        mv.visitLdcInsn(Type.getType("L" + clsToOverride + ";"));
+        final String classNameToOverride = 
method.getDeclaringClass().getName().replace('.', '/');
+        mv.visitLdcInsn(Type.getType("L" + classNameToOverride + ";"));
 
         // the following code generates the bytecode for this line of Java:
         // Method method = <proxy>.class.getMethod("add", new Class[] { <array 
of function argument classes> });
@@ -359,7 +239,7 @@ public class LocalBeanProxyGeneratorImpl
             // keep copy of array on stack
             mv.visitInsn(DUP);
 
-            Class<?> parameterType = parameterTypes[i];
+            final Class<?> parameterType = parameterTypes[i];
 
             // push number onto stack
             pushIntOntoStack(mv, i);
@@ -389,7 +269,7 @@ public class LocalBeanProxyGeneratorImpl
         // the following code generates bytecode equivalent to:
         // return ((<returntype>) invocationHandler.invoke(this, method, new 
Object[] { <function arguments }))[.<primitive>Value()];
 
-        Label l4 = new Label();
+        final Label l4 = new Label();
         mv.visitLabel(l4);
         mv.visitVarInsn(ALOAD, 0);
 
@@ -413,7 +293,7 @@ public class LocalBeanProxyGeneratorImpl
             // keep copy of array on stack
             mv.visitInsn(DUP);
 
-            Class<?> parameterType = parameterTypes[i];
+            final Class<?> parameterType = parameterTypes[i];
 
             // push number onto stack
             pushIntOntoStack(mv, i);
@@ -461,24 +341,28 @@ public class LocalBeanProxyGeneratorImpl
         if (exceptionTypes.length > 0) {
             mv.visitLabel(l2);
             mv.visitVarInsn(ASTORE, length);
-            Label l5 = new Label();
+
+            final Label l5 = new Label();
             mv.visitLabel(l5);
 
             for (int i = 0; i < exceptionTypes.length; i++) {
-                Class<?> exceptionType = exceptionTypes[i];
+                final Class<?> exceptionType = exceptionTypes[i];
 
-                mv.visitLdcInsn(Type.getType("L" + 
exceptionType.getCanonicalName().replaceAll("\\.", "/") + ";"));
+                mv.visitLdcInsn(Type.getType("L" + 
exceptionType.getCanonicalName().replace('.', '/') + ";"));
                 mv.visitVarInsn(ALOAD, length);
                 mv.visitMethodInsn(INVOKEVIRTUAL, 
"java/lang/reflect/InvocationTargetException", "getCause", 
"()Ljava/lang/Throwable;");
                 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", 
"getClass", "()Ljava/lang/Class;");
                 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", 
"equals", "(Ljava/lang/Object;)Z");
-                Label l6 = new Label();
+
+                final Label l6 = new Label();
                 mv.visitJumpInsn(IFEQ, l6);
-                Label l7 = new Label();
+
+                final Label l7 = new Label();
                 mv.visitLabel(l7);
+
                 mv.visitVarInsn(ALOAD, length);
                 mv.visitMethodInsn(INVOKEVIRTUAL, 
"java/lang/reflect/InvocationTargetException", "getCause", 
"()Ljava/lang/Throwable;");
-                mv.visitTypeInsn(CHECKCAST, 
exceptionType.getCanonicalName().replaceAll("\\.", "/"));
+                mv.visitTypeInsn(CHECKCAST, 
exceptionType.getCanonicalName().replace('.', '/'));
                 mv.visitInsn(ATHROW);
                 mv.visitLabel(l6);
 
@@ -502,7 +386,7 @@ public class LocalBeanProxyGeneratorImpl
      * @param type Type the needs to be returned
      * @return The matching bytecode instruction
      */
-    private int getReturnInsn(Class<?> type) {
+    private int getReturnInsn(final Class<?> type) {
         if (type.isPrimitive()) {
             if (Integer.TYPE.equals(type)) {
                 return IRETURN;
@@ -532,7 +416,7 @@ public class LocalBeanProxyGeneratorImpl
      * @param type Type to load
      * @return Bytecode instruction to use
      */
-    private int getVarInsn(Class<?> type) {
+    private int getVarInsn(final Class<?> type) {
         if (type.isPrimitive()) {
             if (Integer.TYPE.equals(type)) {
                 return ILOAD;
@@ -561,7 +445,7 @@ public class LocalBeanProxyGeneratorImpl
      * @param type Type whose primitive method we want to lookup
      * @return The name of the method to use
      */
-    private String getPrimitiveMethod(Class<?> type) {
+    private String getPrimitiveMethod(final Class<?> type) {
         if (Integer.TYPE.equals(type)) {
             return "intValue";
         } else if (Boolean.TYPE.equals(type)) {
@@ -588,7 +472,7 @@ public class LocalBeanProxyGeneratorImpl
      * @param returnType The type to cast to with CHECKCAST
      * @return CHECKCAST parameter
      */
-    String getCastType(Class<?> returnType) {
+    String getCastType(final Class<?> returnType) {
         if (returnType.isPrimitive()) {
             return getWrapperType(returnType);
         } else {
@@ -601,25 +485,25 @@ public class LocalBeanProxyGeneratorImpl
      * @param type
      * @return
      */
-    private String getWrapperType(Class<?> type) {
+    private String getWrapperType(final Class<?> type) {
         if (Integer.TYPE.equals(type)) {
-            return Integer.class.getCanonicalName().replaceAll("\\.", "/");
+            return Integer.class.getCanonicalName().replace('.', '/');
         } else if (Boolean.TYPE.equals(type)) {
-            return Boolean.class.getCanonicalName().replaceAll("\\.", "/");
+            return Boolean.class.getCanonicalName().replace('.', '/');
         } else if (Character.TYPE.equals(type)) {
-            return Character.class.getCanonicalName().replaceAll("\\.", "/");
+            return Character.class.getCanonicalName().replace('.', '/');
         } else if (Byte.TYPE.equals(type)) {
-            return Byte.class.getCanonicalName().replaceAll("\\.", "/");
+            return Byte.class.getCanonicalName().replace('.', '/');
         } else if (Short.TYPE.equals(type)) {
-            return Short.class.getCanonicalName().replaceAll("\\.", "/");
+            return Short.class.getCanonicalName().replace('.', '/');
         } else if (Float.TYPE.equals(type)) {
-            return Float.class.getCanonicalName().replaceAll("\\.", "/");
+            return Float.class.getCanonicalName().replace('.', '/');
         } else if (Long.TYPE.equals(type)) {
-            return Long.class.getCanonicalName().replaceAll("\\.", "/");
+            return Long.class.getCanonicalName().replace('.', '/');
         } else if (Double.TYPE.equals(type)) {
-            return Double.class.getCanonicalName().replaceAll("\\.", "/");
+            return Double.class.getCanonicalName().replace('.', '/');
         } else if (Void.TYPE.equals(type)) {
-            return Void.class.getCanonicalName().replaceAll("\\.", "/");
+            return Void.class.getCanonicalName().replace('.', '/');
         }
 
         throw new IllegalStateException("Type: " + type.getCanonicalName() + " 
is not a primitive type");
@@ -630,7 +514,7 @@ public class LocalBeanProxyGeneratorImpl
      * @param mv
      * @param i
      */
-    private void pushIntOntoStack(MethodVisitor mv, int i) {
+    private void pushIntOntoStack(final MethodVisitor mv, final int i) {
         if (i == 0) {
             mv.visitInsn(ICONST_0);
         } else if (i == 1) {
@@ -659,7 +543,7 @@ public class LocalBeanProxyGeneratorImpl
      * @param type Type of array to create
      * @throws ProxyGenerationException
      */
-    private void createArrayDefinition(MethodVisitor mv, int size, Class<?> 
type) throws ProxyGenerationException {
+    private void createArrayDefinition(final MethodVisitor mv, final int size, 
final Class<?> type) throws ProxyGenerationException {
         // create a new array of java.lang.class (2)
 
         if (size < 0) {
@@ -668,12 +552,12 @@ public class LocalBeanProxyGeneratorImpl
 
         pushIntOntoStack(mv, size);
 
-        mv.visitTypeInsn(ANEWARRAY, type.getCanonicalName().replaceAll("\\.", 
"/"));
+        mv.visitTypeInsn(ANEWARRAY, type.getCanonicalName().replace('.', '/'));
     }
 
 
-    String getMethodSignatureAsString(Class<?> returnType, Class<?>[] 
parameterTypes) {
-        StringBuilder builder = new StringBuilder();
+    String getMethodSignatureAsString(final Class<?> returnType, final 
Class<?>[] parameterTypes) {
+        final StringBuilder builder = new StringBuilder();
         builder.append("(");
         for (Class<?> parameterType : parameterTypes) {
             builder.append(getAsmTypeAsString(parameterType, true));
@@ -690,7 +574,7 @@ public class LocalBeanProxyGeneratorImpl
      * @param type
      * @return
      */
-    private String getPrimitiveLetter(Class<?> type) {
+    private String getPrimitiveLetter(final Class<?> type) {
         if (Integer.TYPE.equals(type)) {
             return "I";
         } else if (Void.TYPE.equals(type)) {
@@ -720,38 +604,158 @@ public class LocalBeanProxyGeneratorImpl
      * @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(Class<?> parameterType, boolean wrap) {
+    public String getAsmTypeAsString(final Class<?> parameterType, final 
boolean wrap) {
         if (parameterType.isArray()) {
             if (parameterType.getComponentType().isPrimitive()) {
-                Class<?> componentType = parameterType.getComponentType();
+                final Class<?> componentType = 
parameterType.getComponentType();
                 return "[" + getPrimitiveLetter(componentType);
             } else {
                 return "[" + 
getAsmTypeAsString(parameterType.getComponentType(), true);
             }
         } else {
-            if (!parameterType.isPrimitive()) {
-                String clsName = parameterType.getCanonicalName();
+            if (parameterType.isPrimitive()) {
+                return getPrimitiveLetter(parameterType);
+            } else {
+                String className = parameterType.getCanonicalName();
 
                 if (parameterType.isMemberClass()) {
-                    int lastDot = clsName.lastIndexOf(".");
-                    clsName = clsName.substring(0, lastDot) + "$" + 
clsName.substring(lastDot + 1);
+                    int lastDot = className.lastIndexOf(".");
+                    className = className.substring(0, lastDot) + "$" + 
className.substring(lastDot + 1);
                 }
+
                 if (wrap) {
-                    return "L" + clsName.replaceAll("\\.", "/") + ";";
+                    return "L" + className.replace('.', '/') + ";";
                 } else {
-                    return clsName.replaceAll("\\.", "/");
+                    return className.replace('.', '/');
                 }
-            } else {
-                return getPrimitiveLetter(parameterType);
             }
         }
     }
 
     static class NonBusinessHandler implements 
java.lang.reflect.InvocationHandler, Serializable {
 
-        public Object invoke(Object proxy, Method method, Object[] args) 
throws Throwable {
+        public Object invoke(final Object proxy, final Method method, final 
Object[] args) throws Throwable {
             throw new EJBException("Calling non-public methods of a local bean 
without any interfaces is not allowed");
         }
 
     }
+
+    /**
+     * The methods of this class model sun.misc.Unsafe which is used 
reflectively
+     */
+    private static class Unsafe {
+
+        // sun.misc.Unsafe
+        private static final Object unsafe;
+        private static final Method defineClass;
+        private static final Method allocateInstance;
+        private static final Method putObject;
+        private static final Method objectFieldOffset;
+
+            static {
+        final Class<?> unsafeClass;
+        try {
+            unsafeClass = AccessController.doPrivileged(new 
PrivilegedAction<Class<?>>() {
+                public Class<?> run() {
+                    try {
+                        return 
Thread.currentThread().getContextClassLoader().loadClass("sun.misc.Unsafe");
+                    } catch (Exception e) {
+                        try {
+                            return 
ClassLoader.getSystemClassLoader().loadClass("sun.misc.Unsafe");
+                        } catch (ClassNotFoundException e1) {
+                            throw new IllegalStateException("Cannot get 
sun.misc.Unsafe", e);
+                        }
+                    }
+                }
+            });
+        } catch (Exception e) {
+            throw new IllegalStateException("Cannot get sun.misc.Unsafe 
class", e);
+        }
+
+        unsafe = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+                try {
+                    Field field = unsafeClass.getDeclaredField("theUnsafe");
+                    field.setAccessible(true);
+                    return field.get(null);
+                } catch (Exception e) {
+                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe", e);
+                }
+            }
+        });
+        allocateInstance = AccessController.doPrivileged(new 
PrivilegedAction<Method>() {
+            public Method run() {
+                try {
+                    Method mtd = 
unsafeClass.getDeclaredMethod("allocateInstance", Class.class);
+                    mtd.setAccessible(true);
+                    return mtd;
+                } catch (Exception e) {
+                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe.allocateInstance", e);
+                }
+            }
+        });
+        objectFieldOffset = AccessController.doPrivileged(new 
PrivilegedAction<Method>() {
+            public Method run() {
+                try {
+                    Method mtd = 
unsafeClass.getDeclaredMethod("objectFieldOffset", Field.class);
+                    mtd.setAccessible(true);
+                    return mtd;
+                } catch (Exception e) {
+                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe.objectFieldOffset", e);
+                }
+            }
+        });
+        putObject = AccessController.doPrivileged(new 
PrivilegedAction<Method>() {
+            public Method run() {
+                try {
+                    Method mtd = unsafeClass.getDeclaredMethod("putObject", 
Object.class, long.class, Object.class);
+                    mtd.setAccessible(true);
+                    return mtd;
+                } catch (Exception e) {
+                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe.putObject", e);
+                }
+            }
+        });
+        defineClass = AccessController.doPrivileged(new 
PrivilegedAction<Method>() {
+            public Method run() {
+                try {
+                    Method mtd = unsafeClass.getDeclaredMethod("defineClass", 
String.class, byte[].class, int.class, int.class, ClassLoader.class, 
ProtectionDomain.class);
+                    mtd.setAccessible(true);
+                    return mtd;
+                } catch (Exception e) {
+                    throw new IllegalStateException("Cannot get 
sun.misc.Unsafe.defineClass", e);
+                }
+            }
+        });
+    }
+        private static Object allocateInstance(final Class clazz) {
+            try {
+                return allocateInstance.invoke(unsafe, clazz);
+            } catch (IllegalAccessException e) {
+                throw new IllegalStateException("Failed to allocateInstance of 
Proxy class " + clazz.getName(), e);
+            } catch (InvocationTargetException e) {
+                Throwable throwable = e.getTargetException() != null ? 
e.getTargetException() : e;
+                throw new IllegalStateException("Failed to allocateInstance of 
Proxy class " + clazz.getName(), throwable);
+            }
+        }
+
+        private static void setValue(final Field field, final Object object, 
final Object value) {
+            final long offset;
+            try {
+                offset = (Long) objectFieldOffset.invoke(unsafe, field);
+            } catch (Exception e) {
+                throw new IllegalStateException("Failed getting offset for: 
field=" + field.getName() + "  class=" + field.getDeclaringClass().getName(), 
e);
+            }
+
+            try {
+                putObject.invoke(unsafe, object, offset, value);
+            } catch (Exception e) {
+                throw new IllegalStateException("Failed putting field=" + 
field.getName() + "  class=" + field.getDeclaringClass().getName(), e);
+            }
+        }
+
+        private static Class defineClass(Class<?> clsToProxy, String 
proxyName, byte[] proxyBytes) throws IllegalAccessException, 
InvocationTargetException {
+            return (Class<?>) defineClass.invoke(unsafe, proxyName, 
proxyBytes, 0, proxyBytes.length, clsToProxy.getClassLoader(), 
clsToProxy.getProtectionDomain());
+        }
+    }
 }


Reply via email to