Author: rmannibucau
Date: Wed May  3 12:12:22 2017
New Revision: 1793640

URL: http://svn.apache.org/viewvc?rev=1793640&view=rev
Log:
OWB-1181 use unsafe to define classes when classloader flavor is not accessible

Modified:
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.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=1793640&r1=1793639&r2=1793640&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
 Wed May  3 12:12:22 2017
@@ -25,6 +25,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.logging.Logger;
@@ -65,6 +66,7 @@ public abstract class AbstractProxyFacto
      */
     private Object unsafe = null;
     private Method unsafeAllocateInstance = null;
+    private Method unsafeDefineClass;
 
     private final int javaVersion;
 
@@ -343,15 +345,30 @@ public abstract class AbstractProxyFacto
             clazz = clazz.getSuperclass();
         } while (defineClassMethod == null && clazz != Object.class);
 
-        if (defineClassMethod == null)
+        if (defineClassMethod != null && !defineClassMethod.isAccessible())
         {
-            throw new ProxyGenerationException("could not find 'defineClass' 
method in the ClassLoader!");
+            try
+            {
+                defineClassMethod.setAccessible(true);
+            }
+            catch (RuntimeException re) // likely j9, let's use unsafe
+            {
+                defineClassMethod = null;
+            }
         }
 
-        defineClassMethod.setAccessible(true);
         try
         {
-            Class<T> definedClass = (Class<T>) 
defineClassMethod.invoke(classLoader, proxyName, proxyBytes, 0, 
proxyBytes.length);
+            final Class<T> definedClass;
+
+            if (defineClassMethod != null)
+            {
+                definedClass = (Class<T>) 
defineClassMethod.invoke(classLoader, proxyName, proxyBytes, 0, 
proxyBytes.length);
+            }
+            else
+            {
+                definedClass = (Class<T>) unsafeDefineClass.invoke(unsafe, 
proxyName, proxyBytes, 0, proxyBytes.length, classLoader, null);
+            }
 
             return (Class<T>) Class.forName(definedClass.getName(), true, 
classLoader);
         }
@@ -744,6 +761,22 @@ public abstract class AbstractProxyFacto
                     }
                 }
             });
+            unsafeDefineClass = AccessController.doPrivileged(new 
PrivilegedAction<Method>()
+            {
+                @Override
+                public Method run()
+                {
+                    try
+                    {
+                        return unsafeClass.getDeclaredMethod("defineClass",
+                                String.class, byte[].class, int.class, 
int.class, ClassLoader.class, ProtectionDomain.class);
+                    }
+                    catch (Exception e)
+                    {
+                        throw new IllegalStateException("Cannot get 
Unsafe.defineClass", e);
+                    }
+                }
+            });
         }
     }
 


Reply via email to