openwebbeans-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tandrasc...@apache.org
Subject svn commit: r1848029 - in /openwebbeans/branches/owb_1.7.x: ./ distribution/ distribution/src/assembly/ webbeans-impl/ webbeans-impl/src/main/java/org/apache/webbeans/proxy/ webbeans-impl/src/test/java/org/apache/webbeans/proxy/ webbeans-impl/src/test/...
Date Mon, 03 Dec 2018 10:10:09 GMT
Author: tandraschko
Date: Mon Dec  3 10:10:09 2018
New Revision: 1848029

URL: http://svn.apache.org/viewvc?rev=1848029&view=rev
Log:
OWB-1270 Backport Java11 aligments

Added:
    openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java
    openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/proxy/
    openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/proxy/UnsafeTest.java
    openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/test/injection/generics/FastMatchingGenericsTest.java
Modified:
    openwebbeans/branches/owb_1.7.x/distribution/pom.xml
    openwebbeans/branches/owb_1.7.x/distribution/src/assembly/dist-binary.xml
    openwebbeans/branches/owb_1.7.x/pom.xml
    openwebbeans/branches/owb_1.7.x/webbeans-impl/pom.xml
    openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
    openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
    openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java
    openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java

Modified: openwebbeans/branches/owb_1.7.x/distribution/pom.xml
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/distribution/pom.xml?rev=1848029&r1=1848028&r2=1848029&view=diff
==============================================================================
--- openwebbeans/branches/owb_1.7.x/distribution/pom.xml (original)
+++ openwebbeans/branches/owb_1.7.x/distribution/pom.xml Mon Dec  3 10:10:09 2018
@@ -145,7 +145,7 @@
         </dependency>
         <dependency>
             <groupId>org.apache.xbean</groupId>
-            <artifactId>xbean-asm6-shaded</artifactId>
+            <artifactId>xbean-asm7-shaded</artifactId>
         </dependency>
 
 

Modified: openwebbeans/branches/owb_1.7.x/distribution/src/assembly/dist-binary.xml
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/distribution/src/assembly/dist-binary.xml?rev=1848029&r1=1848028&r2=1848029&view=diff
==============================================================================
--- openwebbeans/branches/owb_1.7.x/distribution/src/assembly/dist-binary.xml (original)
+++ openwebbeans/branches/owb_1.7.x/distribution/src/assembly/dist-binary.xml Mon Dec  3 10:10:09
2018
@@ -73,7 +73,7 @@ under the License.
             <includes>
                 <include>org.apache.openwebbeans:openwebbeans-impl:jar</include>
                 <include>org.apache.xbean:xbean-finder-shaded:jar</include>
-                <include>org.apache.xbean:xbean-asm6-shaded:jar</include>
+                <include>org.apache.xbean:xbean-asm7-shaded:jar</include>
             </includes>
         </dependencySet>
 

Modified: openwebbeans/branches/owb_1.7.x/pom.xml
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/pom.xml?rev=1848029&r1=1848028&r2=1848029&view=diff
==============================================================================
--- openwebbeans/branches/owb_1.7.x/pom.xml (original)
+++ openwebbeans/branches/owb_1.7.x/pom.xml Mon Dec  3 10:10:09 2018
@@ -71,7 +71,7 @@
         <geronimo_validation.version>1.1</geronimo_validation.version>
         <tomcat7.version>7.0.73</tomcat7.version>
         <myfaces.version>2.2.12</myfaces.version>
-        <xbean.version>4.8</xbean.version>
+        <xbean.version>4.11</xbean.version>
         <arquillian.version>1.1.13.Final</arquillian.version>
         <cdi.tck.version>1.2.8.Final</cdi.tck.version>
         <httpclient.version>4.5.2</httpclient.version>
@@ -574,7 +574,7 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.xbean</groupId>
-                <artifactId>xbean-asm6-shaded</artifactId>
+                <artifactId>xbean-asm7-shaded</artifactId>
                 <version>${xbean.version}</version>
             </dependency>
 

Modified: openwebbeans/branches/owb_1.7.x/webbeans-impl/pom.xml
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/webbeans-impl/pom.xml?rev=1848029&r1=1848028&r2=1848029&view=diff
==============================================================================
--- openwebbeans/branches/owb_1.7.x/webbeans-impl/pom.xml (original)
+++ openwebbeans/branches/owb_1.7.x/webbeans-impl/pom.xml Mon Dec  3 10:10:09 2018
@@ -49,7 +49,7 @@
         </dependency>
         <dependency>
             <groupId>org.apache.xbean</groupId>
-            <artifactId>xbean-asm6-shaded</artifactId>
+            <artifactId>xbean-asm7-shaded</artifactId>
         </dependency>
 
         <dependency>

Modified: openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java?rev=1848029&r1=1848028&r2=1848029&view=diff
==============================================================================
--- openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
(original)
+++ openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
Mon Dec  3 10:10:09 2018
@@ -18,31 +18,24 @@
  */
 package org.apache.webbeans.proxy;
 
-import static org.apache.xbean.asm6.ClassReader.SKIP_DEBUG;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.exception.ProxyGenerationException;
+import org.apache.webbeans.exception.WebBeansException;
+import org.apache.xbean.asm7.ClassReader;
+import org.apache.xbean.asm7.ClassWriter;
+import org.apache.xbean.asm7.MethodVisitor;
+import org.apache.xbean.asm7.Opcodes;
+import org.apache.xbean.asm7.Type;
+import org.apache.xbean.asm7.shade.commons.EmptyVisitor;
 
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
-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 java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.logging.Logger;
 
-import org.apache.webbeans.config.WebBeansContext;
-import org.apache.webbeans.exception.ProxyGenerationException;
-import org.apache.webbeans.exception.WebBeansException;
-import org.apache.webbeans.logger.WebBeansLoggerFacade;
-import org.apache.xbean.asm6.ClassReader;
-import org.apache.xbean.asm6.ClassWriter;
-import org.apache.xbean.asm6.MethodVisitor;
-import org.apache.xbean.asm6.Opcodes;
-import org.apache.xbean.asm6.Type;
-import org.apache.xbean.asm6.shade.commons.EmptyVisitor;
+import static org.apache.xbean.asm7.ClassReader.SKIP_DEBUG;
 
 /**
  * Base class for all OWB Proxy factories
@@ -58,21 +51,10 @@ public abstract class AbstractProxyFacto
      */
     public static final int MODIFIER_VARARGS = 0x00000080;;
 
-
-    private static final Logger logger = WebBeansLoggerFacade.getLogger(AbstractProxyFactory.class);
-
+    protected final Unsafe unsafe;
 
     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 = null;
-    private Method unsafeDefineClass;
-
     private final int javaVersion;
 
 
@@ -88,7 +70,7 @@ public abstract class AbstractProxyFacto
     {
         this.webBeansContext = webBeansContext;
         javaVersion = determineDefaultJavaVersion();
-        initializeUnsafe();
+        unsafe = new Unsafe();
     }
 
     private int determineDefaultJavaVersion()
@@ -108,6 +90,14 @@ public abstract class AbstractProxyFacto
             {
                 return Opcodes.V9;
             }
+            else if (javaVersionProp.startsWith("10"))
+            {
+                return Opcodes.V10;
+            }
+            else if (javaVersionProp.startsWith("11"))
+            {
+                return Opcodes.V11;
+            }
         }
 
         // the fallback is the lowest one to ensure it supports all possible classes of current
environments
@@ -250,7 +240,7 @@ public abstract class AbstractProxyFacto
                 sortOutDuplicateMethods(nonInterceptedMethods),
                 constructor);
 
-        return defineAndLoadClass(classLoader, proxyClassName, proxyBytes);
+        return unsafe.defineAndLoadClass(classLoader, proxyClassName, proxyBytes);
     }
 
     private Method[] sortOutDuplicateMethods(Method[] methods)
@@ -357,79 +347,6 @@ public abstract class AbstractProxyFacto
     }
 
 
-    /**
-     * The 'defineClass' method on the ClassLoader is protected, thus we need to invoke it
via reflection.
-     * @return the Class which got loaded in the classloader
-     */
-    private <T> Class<T> defineAndLoadClass(ClassLoader classLoader, String proxyName,
byte[] proxyBytes)
-            throws ProxyGenerationException
-    {
-        Class<?> clazz = classLoader.getClass();
-
-        Method defineClassMethod = null;
-        do
-        {
-            try
-            {
-                defineClassMethod = clazz.getDeclaredMethod("defineClass", String.class,
byte[].class, int.class, int.class);
-            }
-            catch (NoSuchMethodException e)
-            {
-                // do nothing, we need to search the superclass
-            }
-
-            clazz = clazz.getSuperclass();
-        } while (defineClassMethod == null && clazz != Object.class);
-
-        if (defineClassMethod != null && !defineClassMethod.isAccessible())
-        {
-            try
-            {
-                defineClassMethod.setAccessible(true);
-            }
-            catch (RuntimeException re) // likely j9, let's use unsafe
-            {
-                defineClassMethod = null;
-            }
-        }
-
-        try
-        {
-            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);
-        }
-        catch (InvocationTargetException le) // if concurrent calls are done then ensure
to just reload the created one
-        {
-            if (LinkageError.class.isInstance(le.getCause()))
-            {
-                try
-                {
-                    return (Class<T>) Class.forName(proxyName.replace('/', '.'), true,
classLoader);
-                }
-                catch (ClassNotFoundException e)
-                {
-                    // default error handling
-                }
-            }
-            throw new ProxyGenerationException(le.getCause());
-        }
-        catch (Throwable e)
-        {
-            throw new ProxyGenerationException(e);
-        }
-    }
-
-
     protected boolean unproxyableMethod(Method delegatedMethod)
     {
         int modifiers = delegatedMethod.getModifiers();
@@ -691,131 +608,6 @@ public abstract class AbstractProxyFacto
         mv.visitInsn(getReturnInsn(returnType));
     }
 
-    protected <T> T unsafeNewInstance(Class<T> clazz)
-    {
-        try
-        {
-            if (unsafeAllocateInstance != null)
-            {
-                return (T) unsafeAllocateInstance.invoke(unsafe, clazz);
-            }
-            else
-            {
-                try
-                {
-                    return (T) clazz.newInstance();
-                }
-                catch (InstantiationException e)
-                {
-                    throw new IllegalStateException("Failed to allocateInstance of Proxy
class " + clazz.getName(), e);
-                }
-            }
-        }
-        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<?>>()
-            {
-                @Override
-                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>()
-        {
-            @Override
-            public Object run()
-            {
-                try
-                {
-                    Field field = unsafeClass.getDeclaredField("theUnsafe");
-                    field.setAccessible(true);
-                    return field.get(null);
-                }
-                catch (Exception e)
-                {
-                    logger.warning("ATTENTION: Cannot get sun.misc.Unsafe - will use newInstance()
instead! Intended for GAE only!");
-                    return null;
-                }
-            }
-        });
-
-        this.unsafe = unsafe;
-
-        if (unsafe != null)
-        {
-            unsafeAllocateInstance = AccessController.doPrivileged(new PrivilegedAction<Method>()
-            {
-                @Override
-                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);
-                    }
-                }
-            });
-            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);
-                    }
-                }
-            });
-        }
-    }
-
     /**
      * Create an Object[] parameter which contains all the parameters of the currently invoked
method
      * and store this array for use in the call stack.

Modified: openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java?rev=1848029&r1=1848028&r2=1848029&view=diff
==============================================================================
--- openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
(original)
+++ openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/InterceptorDecoratorProxyFactory.java
Mon Dec  3 10:10:09 2018
@@ -25,11 +25,11 @@ import org.apache.webbeans.exception.Web
 import org.apache.webbeans.logger.WebBeansLoggerFacade;
 import org.apache.webbeans.util.Asserts;
 import org.apache.webbeans.util.ExceptionUtil;
-import org.apache.xbean.asm6.ClassWriter;
-import org.apache.xbean.asm6.Label;
-import org.apache.xbean.asm6.MethodVisitor;
-import org.apache.xbean.asm6.Opcodes;
-import org.apache.xbean.asm6.Type;
+import org.apache.xbean.asm7.ClassWriter;
+import org.apache.xbean.asm7.Label;
+import org.apache.xbean.asm7.MethodVisitor;
+import org.apache.xbean.asm7.Opcodes;
+import org.apache.xbean.asm7.Type;
 
 import javax.enterprise.inject.spi.Bean;
 import java.io.ObjectStreamException;
@@ -84,7 +84,7 @@ public class InterceptorDecoratorProxyFa
 
         try
         {
-            T proxy = unsafeNewInstance(proxyClass);
+            T proxy = unsafe.unsafeNewInstance(proxyClass);
 
             Field delegateField = proxy.getClass().getDeclaredField(FIELD_PROXIED_INSTANCE);
             delegateField.setAccessible(true);

Modified: openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java?rev=1848029&r1=1848028&r2=1848029&view=diff
==============================================================================
--- openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java
(original)
+++ openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/NormalScopeProxyFactory.java
Mon Dec  3 10:10:09 2018
@@ -41,10 +41,10 @@ import org.apache.webbeans.intercept.Nor
 import org.apache.webbeans.util.ClassUtil;
 import org.apache.webbeans.util.ExceptionUtil;
 import org.apache.webbeans.util.WebBeansUtil;
-import org.apache.xbean.asm6.ClassWriter;
-import org.apache.xbean.asm6.MethodVisitor;
-import org.apache.xbean.asm6.Opcodes;
-import org.apache.xbean.asm6.Type;
+import org.apache.xbean.asm7.ClassWriter;
+import org.apache.xbean.asm7.MethodVisitor;
+import org.apache.xbean.asm7.Opcodes;
+import org.apache.xbean.asm7.Type;
 
 /**
  * This factory creates proxies which delegate the
@@ -291,7 +291,7 @@ public class NormalScopeProxyFactory ext
     {
         try
         {
-            T proxy = unsafeNewInstance(proxyClass);
+            T proxy = unsafe.unsafeNewInstance(proxyClass);
 
             Field delegateField = proxy.getClass().getDeclaredField(FIELD_INSTANCE_PROVIDER);
             delegateField.setAccessible(true);
@@ -508,7 +508,7 @@ public class NormalScopeProxyFactory ext
      * if targetMethod is protected. Please see Java LangSpec 6.6.2 about the complex
      * rules for calling 'protected' methods.
      *
-     * @see #generateDelegationMethod(org.apache.xbean.asm6.ClassWriter, java.lang.reflect.Method,
int, Class, String)
+     * @see #generateDelegationMethod(org.apache.xbean.asm7.ClassWriter, java.lang.reflect.Method,
int, Class, String)
      */
     @SuppressWarnings("unused")
     public static Object delegateProtectedMethod(Method method, Object instance, Object[]
params)

Modified: openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java?rev=1848029&r1=1848028&r2=1848029&view=diff
==============================================================================
--- openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java
(original)
+++ openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java
Mon Dec  3 10:10:09 2018
@@ -24,16 +24,16 @@ import java.lang.reflect.Modifier;
 import java.util.List;
 
 import org.apache.webbeans.config.WebBeansContext;
-import org.apache.webbeans.exception.ProxyGenerationException;
-import org.apache.webbeans.exception.WebBeansConfigurationException;
-import org.apache.webbeans.util.ClassUtil;
-import org.apache.xbean.asm6.ClassWriter;
-import org.apache.xbean.asm6.MethodVisitor;
-import org.apache.xbean.asm6.Opcodes;
-import org.apache.xbean.asm6.Type;
-
-import javax.enterprise.inject.spi.AnnotatedConstructor;
-import javax.enterprise.inject.spi.AnnotatedType;
+import org.apache.webbeans.exception.ProxyGenerationException;
+import org.apache.webbeans.exception.WebBeansConfigurationException;
+import org.apache.webbeans.util.ClassUtil;
+import org.apache.xbean.asm7.ClassWriter;
+import org.apache.xbean.asm7.MethodVisitor;
+import org.apache.xbean.asm7.Opcodes;
+import org.apache.xbean.asm7.Type;
+
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedType;
 import javax.inject.Inject;
 
 /**

Added: openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java?rev=1848029&view=auto
==============================================================================
--- openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java
(added)
+++ openwebbeans/branches/owb_1.7.x/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java
Mon Dec  3 10:10:09 2018
@@ -0,0 +1,258 @@
+/*
+ * 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;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.webbeans.exception.ProxyGenerationException;
+import org.apache.webbeans.logger.WebBeansLoggerFacade;
+
+public class Unsafe
+{
+    /**
+     * contains the instance of sun.misc.Unsafe.
+     * We use it for creating the proxy instance without fully
+     * initializing the class.
+     */
+    private Object unsafe;
+    private Method unsafeAllocateInstance;
+    private final AtomicReference<Method> unsafeDefineClass = new AtomicReference<>();
+
+    public Unsafe()
+    {
+        final Class<?> unsafeClass = getUnsafeClass();
+
+        this.unsafe = AccessController.doPrivileged(new PrivilegedAction<Object>()
+        {
+            @Override
+            public Object run()
+            {
+                try
+                {
+                    Field field = unsafeClass.getDeclaredField("theUnsafe");
+                    field.setAccessible(true);
+                    return field.get(null);
+                }
+                catch (Exception e)
+                {
+                    WebBeansLoggerFacade.getLogger(Unsafe.class)
+                            .info("Cannot get sun.misc.Unsafe - will use newInstance() instead!");
+                    return null;
+                }
+            }
+        });
+
+        if (unsafe != null)
+        {
+            unsafeAllocateInstance = AccessController.doPrivileged(new PrivilegedAction<Method>()
+            {
+                @Override
+                public Method run()
+                {
+                    try
+                    {
+                        Method mtd = unsafeClass.getDeclaredMethod("allocateInstance", Class.class);
+                        mtd.setAccessible(true);
+                        return mtd;
+                    }
+                    catch (Exception e)
+                    {
+                        return null; // use newInstance()
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * The 'defineClass' method on the ClassLoader is protected, thus we need to invoke it
via reflection.
+     * @return the Class which got loaded in the classloader
+     */
+    public <T> Class<T> defineAndLoadClass(ClassLoader classLoader, String proxyName,
byte[] proxyBytes)
+            throws ProxyGenerationException
+    {
+        Class<?> clazz = classLoader.getClass();
+
+        Method defineClassMethod = null;
+        do
+        {
+            try
+            {
+                defineClassMethod = clazz.getDeclaredMethod("defineClass", String.class,
byte[].class, int.class, int.class);
+            }
+            catch (NoSuchMethodException e)
+            {
+                // do nothing, we need to search the superclass
+            }
+
+            clazz = clazz.getSuperclass();
+        } while (defineClassMethod == null && clazz != Object.class);
+
+        if (defineClassMethod != null && !defineClassMethod.isAccessible())
+        {
+            try
+            {
+                defineClassMethod.setAccessible(true);
+            }
+            catch (RuntimeException re) // likely j9, let's use unsafe
+            {
+                defineClassMethod = null;
+            }
+        }
+
+        try
+        {
+            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);
+        }
+        catch (InvocationTargetException le) // if concurrent calls are done then ensure
to just reload the created one
+        {
+            if (LinkageError.class.isInstance(le.getCause()))
+            {
+                try
+                {
+                    return (Class<T>) Class.forName(proxyName.replace('/', '.'), true,
classLoader);
+                }
+                catch (ClassNotFoundException e)
+                {
+                    // default error handling
+                }
+            }
+            throw new ProxyGenerationException(le.getCause());
+        }
+        catch (Throwable e)
+        {
+            throw new ProxyGenerationException(e);
+        }
+    }
+
+    private Method unsafeDefineClass()
+    {
+        Method value = unsafeDefineClass.get();
+        if (value == null)
+        {
+            synchronized (this)
+            {
+                final Class<?> unsafeClass = getUnsafeClass();
+                value = 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 (final Exception e)
+                        {
+                            throw new IllegalStateException("Cannot get Unsafe.defineClass
or equivalent", e);
+                        }
+                    }
+                });
+                unsafeDefineClass.compareAndSet(null, value);
+            }
+        }
+        return value;
+    }
+
+    public <T> T unsafeNewInstance(Class<T> clazz)
+    {
+        try
+        {
+            if (unsafeAllocateInstance != null)
+            {
+                return (T) unsafeAllocateInstance.invoke(unsafe, clazz);
+            }
+            else
+            {
+                try
+                {
+                    return clazz.getConstructor().newInstance();
+                }
+                catch (final Exception e)
+                {
+                    throw new IllegalStateException("Failed to allocateInstance of Proxy
class " + clazz.getName(), e);
+                }
+            }
+        }
+        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 Class<?> getUnsafeClass()
+    {
+        Class<?> unsafeClass;
+        try
+        {
+            unsafeClass = AccessController.doPrivileged(new PrivilegedAction<Class<?>>()
+            {
+                @Override
+                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 (final Exception e)
+        {
+            throw new IllegalStateException("Cannot get sun.misc.Unsafe class", e);
+        }
+        return unsafeClass;
+    }
+}

Added: openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/proxy/UnsafeTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/proxy/UnsafeTest.java?rev=1848029&view=auto
==============================================================================
--- openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/proxy/UnsafeTest.java
(added)
+++ openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/proxy/UnsafeTest.java
Mon Dec  3 10:10:09 2018
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import static org.apache.webbeans.util.Asserts.assertNotNull;
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+
+public class UnsafeTest {
+    @Test
+    public void ensureUnsafeIsAvailable()
+    {
+        final Unsafe unsafe = new Unsafe();
+        final SpyConstructor obj = unsafe.unsafeNewInstance(SpyConstructor.class);
+        assertNotNull(obj);
+        assertFalse(obj.called);
+    }
+
+    public static class SpyConstructor
+    {
+        private boolean called;
+
+        public SpyConstructor()
+        {
+            called = true;
+        }
+    }
+}

Added: openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/test/injection/generics/FastMatchingGenericsTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/test/injection/generics/FastMatchingGenericsTest.java?rev=1848029&view=auto
==============================================================================
--- openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/test/injection/generics/FastMatchingGenericsTest.java
(added)
+++ openwebbeans/branches/owb_1.7.x/webbeans-impl/src/test/java/org/apache/webbeans/test/injection/generics/FastMatchingGenericsTest.java
Mon Dec  3 10:10:09 2018
@@ -0,0 +1,99 @@
+/*
+ * 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.test.injection.generics;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+import org.apache.webbeans.config.OwbParametrizedTypeImpl;
+import org.apache.webbeans.test.AbstractUnitTest;
+import org.junit.Test;
+
+public class FastMatchingGenericsTest extends AbstractUnitTest
+{
+    @Test
+    public void concreteGenericsAreNotAmbiguous()
+    {
+        startContainer(StringRepo.class, IntRepo.class);
+        final Object stringRepo = getInstance(new OwbParametrizedTypeImpl(null, Repo.class,
String.class));
+        assertNotNull(stringRepo);
+        assertEquals("string", Repo.class.cast(stringRepo).get());
+        validateIntRepoIsOk();
+    }
+
+    @Test
+    public void genericGenericsAreNotAmbiguous()
+    {
+        startContainer(IntRepo.class, StringRepo.class, ConcreteRepo.class);
+        final ConcreteRepo stringRepo = getInstance(ConcreteRepo.class);
+        assertNotNull(stringRepo);
+        assertEquals("string", stringRepo.get());
+        validateIntRepoIsOk();
+    }
+
+    // just to ensure String is not a particular case or there is a iterator().next() breaking
other cases
+    private void validateIntRepoIsOk()
+    {
+        final Object intRepo = getInstance(new OwbParametrizedTypeImpl(null, Repo.class,
Integer.class));
+        assertNotNull(intRepo);
+        assertEquals(1, Repo.class.cast(intRepo).get());
+    }
+
+    public interface Repo<A> {
+        A get();
+    }
+
+    public static abstract class BaseRepoAware<A>
+    {
+        @Inject
+        protected Repo<A> repo;
+    }
+
+    @ApplicationScoped
+    public static class ConcreteRepo extends BaseRepoAware<String>
+    {
+        public String get()
+        {
+            return repo.get();
+        }
+    }
+
+    @ApplicationScoped
+    public static class StringRepo implements Repo<String>
+    {
+        @Override
+        public String get()
+        {
+            return "string";
+        }
+    }
+
+    @ApplicationScoped
+    public static class IntRepo implements Repo<Integer>
+    {
+        @Override
+        public Integer get()
+        {
+            return 1;
+        }
+    }
+}



Mime
View raw message