jdk 11 compatibility
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/84f96946 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/84f96946 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/84f96946 Branch: refs/heads/master Commit: 84f9694678403e326f48e504aa5e9145ca7cbe97 Parents: e157f6d Author: Vicente Rossello <[email protected]> Authored: Wed Aug 15 23:55:01 2018 +0200 Committer: Jonathan Gallimore <[email protected]> Committed: Mon Aug 20 14:37:40 2018 +0100 ---------------------------------------------------------------------- .../util/proxy/LocalBeanProxyFactory.java | 37 +++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/84f96946/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyFactory.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyFactory.java index 8a0dd8a..a36f7b8 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyFactory.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/LocalBeanProxyFactory.java @@ -17,6 +17,9 @@ package org.apache.openejb.util.proxy; + +import org.apache.openejb.util.LogCategory; +import org.apache.openejb.util.Logger; import org.apache.openejb.util.Debug; import org.apache.xbean.asm6.ClassWriter; import org.apache.xbean.asm6.Label; @@ -47,6 +50,8 @@ import java.util.concurrent.locks.ReentrantLock; public class LocalBeanProxyFactory implements Opcodes { + private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, QueryProxy.class); + public static final InvocationHandler NON_BUSINESS_HANDLER = new NonBusinessHandler(); private static final String BUSSINESS_HANDLER_NAME = "businessHandler"; @@ -700,7 +705,7 @@ public class LocalBeanProxyFactory implements Opcodes { // sun.misc.Unsafe private static final Object unsafe; - private static final Method defineClass; + private static final Method unsafeDefineClass; private static final Method allocateInstance; private static final Method putObject; private static final Method objectFieldOffset; @@ -774,7 +779,7 @@ public class LocalBeanProxyFactory implements Opcodes { } } }); - defineClass = AccessController.doPrivileged(new PrivilegedAction<Method>() { + unsafeDefineClass = AccessController.doPrivileged(new PrivilegedAction<Method>() { @Override public Method run() { try { @@ -782,7 +787,8 @@ public class LocalBeanProxyFactory implements Opcodes { mtd.setAccessible(true); return mtd; } catch (final Exception e) { - throw new IllegalStateException("Cannot get sun.misc.Unsafe.defineClass", e); + LOGGER.debug("Unsafe's defineClass not available, will use classloader's defineClass"); + return null; } } }); @@ -816,8 +822,31 @@ public class LocalBeanProxyFactory implements Opcodes { // it is super important to pass a classloader as first parameter otherwise if API class is in a "permanent" classloader then it will leak public static Class defineClass(final ClassLoader loader, final Class<?> clsToProxy, final String proxyName, final byte[] proxyBytes) throws IllegalAccessException, InvocationTargetException { - return (Class<?>) defineClass.invoke(unsafe, proxyName, proxyBytes, 0, proxyBytes.length, loader, clsToProxy.getProtectionDomain()); + if (unsafeDefineClass != null) { + return (Class<?>) unsafeDefineClass.invoke(unsafe, proxyName, proxyBytes, 0, proxyBytes.length, loader, clsToProxy.getProtectionDomain()); + } else { + return (Class) getClassLoaderDefineClassMethod(loader).invoke(loader, proxyName, proxyBytes, 0, proxyBytes.length, clsToProxy.getProtectionDomain()); + } + } + + private static Method getClassLoaderDefineClassMethod(ClassLoader classLoader) { + Class<?> clazz = classLoader.getClass(); + Method defineClassMethod = null; + do { + try { + defineClassMethod = clazz.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class, ProtectionDomain.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()) { + defineClassMethod.setAccessible(true); + } + return defineClassMethod; } + } @Target(ElementType.TYPE)
