You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by ta...@apache.org on 2018/12/03 10:10:09 UTC
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/...
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;
+ }
+ }
+}