You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2013/01/21 13:12:45 UTC

svn commit: r1436298 - in /openwebbeans/trunk/webbeans-impl/src: main/java/org/apache/webbeans/proxy/ test/java/org/apache/webbeans/newtests/interceptors/factory/

Author: struberg
Date: Mon Jan 21 12:12:45 2013
New Revision: 1436298

URL: http://svn.apache.org/viewvc?rev=1436298&view=rev
Log:
OWB-344 use Davids trick to not fully initialize proxies

Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java?rev=1436298&r1=1436297&r2=1436298&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java Mon Jan 21 12:12:45 2013
@@ -18,9 +18,12 @@
  */
 package org.apache.webbeans.proxy;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.exception.WebBeansException;
@@ -39,6 +42,15 @@ public abstract class AbstractProxyFacto
     protected WebBeansContext webBeansContext;
 
     /**
+     * contains the instance of sun.misc.Unsafe.
+     * We use it for creating the proxy instance without fully
+     * initializing the class.
+     */
+    private Object unsafe = null;
+    private Method unsafeAllocateInstance;
+
+
+    /**
      * The name of the field which stores the passivationID of the Bean this proxy serves.
      * This is needed in case the proxy gets de-serialized back into a JVM
      * which didn't have this bean loaded yet.
@@ -49,6 +61,7 @@ public abstract class AbstractProxyFacto
     protected AbstractProxyFactory(WebBeansContext webBeansContext)
     {
         this.webBeansContext = webBeansContext;
+        initializeUnsafe();
     }
 
     /**
@@ -90,7 +103,6 @@ public abstract class AbstractProxyFacto
     protected abstract void delegateNonInterceptedMethods(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, Method[] noninterceptedMethods)
             throws ProxyGenerationException;
 
-
     /**
      * Detect a free classname based on the given one
      * @param proxyClassName
@@ -529,4 +541,94 @@ public abstract class AbstractProxyFacto
         mv.visitInsn(getReturnInsn(returnType));
     }
 
+    protected <T> T unsafeNewInstance(Class<T> clazz)
+    {
+        T instance = null;
+
+        try
+        {
+            return (T) unsafeAllocateInstance.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 void initializeUnsafe()
+    {
+        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);
+        }
+
+        Object 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);
+                }
+            }
+        });
+
+        this.unsafe = unsafe;
+
+        this.unsafeAllocateInstance = 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);
+                }
+            }
+        });
+    }
+
 }

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java?rev=1436298&r1=1436297&r2=1436298&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java Mon Jan 21 12:12:45 2013
@@ -71,7 +71,7 @@ public class InterceptorDecoratorProxyFa
     {
         try
         {
-            T proxy = proxyClass.newInstance();
+            T proxy = unsafeNewInstance(proxyClass);
 
             Field delegateField = proxy.getClass().getDeclaredField(FIELD_PROXIED_INSTANCE);
             delegateField.setAccessible(true);
@@ -83,10 +83,6 @@ public class InterceptorDecoratorProxyFa
 
             return proxy;
         }
-        catch (InstantiationException e)
-        {
-            throw new ProxyGenerationException(e);
-        }
         catch (IllegalAccessException e)
         {
             throw new ProxyGenerationException(e);

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java?rev=1436298&r1=1436297&r2=1436298&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java Mon Jan 21 12:12:45 2013
@@ -216,7 +216,7 @@ public class NormalScopeProxyFactory ext
     {
         try
         {
-            T proxy = proxyClass.newInstance();
+            T proxy = unsafeNewInstance(proxyClass);
 
             Field delegateField = proxy.getClass().getDeclaredField(FIELD_INSTANCE_PROVIDER);
             delegateField.setAccessible(true);
@@ -224,10 +224,6 @@ public class NormalScopeProxyFactory ext
 
             return proxy;
         }
-        catch (InstantiationException e)
-        {
-            throw new ProxyGenerationException(e);
-        }
         catch (IllegalAccessException e)
         {
             throw new ProxyGenerationException(e);

Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java?rev=1436298&r1=1436297&r2=1436298&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/InterceptorDecoratorProxyFactoryTest.java Mon Jan 21 12:12:45 2013
@@ -18,7 +18,6 @@
  */
 package org.apache.webbeans.newtests.interceptors.factory;
 
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.URL;
@@ -70,14 +69,6 @@ public class InterceptorDecoratorProxyFa
         ClassInterceptedClass proxy = pf.createProxyInstance(proxyClass, internalInstance, testInvocationHandler);
         Assert.assertNotNull(proxy);
 
-        // we need to get the field from the proxy via reflection
-        // otherwise we will end up seeing the proxied method on the internal state
-        Field field = proxy.getClass().getSuperclass().getDeclaredField("defaultCtInvoked");
-        Assert.assertNotNull(field);
-        field.setAccessible(true);
-        Boolean isDefaultCtInvoked = (Boolean) field.get(proxy);
-        Assert.assertTrue(isDefaultCtInvoked);
-
         Assert.assertTrue(proxy instanceof OwbInterceptorProxy);
 
         proxy.setMeaningOfLife(42);