diff options
author | Christian Beikov <christian.beikov@gmail.com> | 2018-06-22 09:03:55 +0200 |
---|---|---|
committer | Christian Beikov <christian.beikov@gmail.com> | 2018-06-22 09:06:01 +0200 |
commit | 92ee53b460fcde5f8585780ccd829d5034889e71 (patch) | |
tree | b14ab5d8bfb522e97714e14fe64a2837a5c3a402 | |
parent | dfce4e4b3d5fbd253d720867eab8e6146e0de516 (diff) | |
download | javassist-92ee53b460fcde5f8585780ccd829d5034889e71.tar.gz javassist-92ee53b460fcde5f8585780ccd829d5034889e71.zip |
[#171] Allow running on JDK 8 and possibly on JDK 7 as well. Fixes #171
-rw-r--r-- | src/main/javassist/util/proxy/DefineClassHelper.java | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/src/main/javassist/util/proxy/DefineClassHelper.java b/src/main/javassist/util/proxy/DefineClassHelper.java index 4d6c9f9d..38691118 100644 --- a/src/main/javassist/util/proxy/DefineClassHelper.java +++ b/src/main/javassist/util/proxy/DefineClassHelper.java @@ -51,8 +51,12 @@ public class DefineClassHelper Class<?> defineClass(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain) throws ClassFormatError { - if (stack.getCallerClass() != SecuredPrivileged.JAVA_9.getClass()) - throw new IllegalAccessError("Access denied for caller."); + try { + if (getCallerClass.invoke(stack) != SecuredPrivileged.JAVA_9.getClass()) + throw new IllegalAccessError("Access denied for caller."); + } catch (Exception e) { + throw new RuntimeException("cannot initialize", e); + } try { return (Class<?>) defineClass.invokeWithArguments( sunMiscUnsafeTheUnsafe.theUnsafe, @@ -64,14 +68,40 @@ public class DefineClassHelper } } } - private final StackWalker stack = StackWalker - .getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + private final Object stack; + private final Method getCallerClass; + { + Class<?> stackWalkerClass = null; + try { + stackWalkerClass = Class.forName("java.lang.StackWalker"); + } catch (ClassNotFoundException e) { + // Skip initialization when the class doesn't exist i.e. we are on JDK < 9 + } + if (stackWalkerClass != null) { + try { + Class<?> optionClass = Class.forName("java.lang.StackWalker$Option"); + stack = stackWalkerClass.getMethod("getInstance", optionClass) + // The first one is RETAIN_CLASS_REFERENCE + .invoke(null, optionClass.getEnumConstants()[0]); + getCallerClass = stackWalkerClass.getMethod("getCallerClass"); + } catch (Throwable e) { + throw new RuntimeException("cannot initialize", e); + } + } else { + stack = null; + getCallerClass = null; + } + } private final ReferencedUnsafe sunMiscUnsafe = getReferencedUnsafe(); private final ReferencedUnsafe getReferencedUnsafe() { - if (null != SecuredPrivileged.JAVA_9 - && stack.getCallerClass() != this.getClass()) - throw new IllegalAccessError("Access denied for caller."); + try { + if (null != SecuredPrivileged.JAVA_9 + && getCallerClass.invoke(stack) != this.getClass()) + throw new IllegalAccessError("Access denied for caller."); + } catch (Exception e) { + throw new RuntimeException("cannot initialize", e); + } try { SecurityActions.TheUnsafe usf = SecurityActions.getSunMiscUnsafeAnonymously(); List<Method> defineClassMethod = usf.methods.get("defineClass"); @@ -91,8 +121,12 @@ public class DefineClassHelper ClassLoader loader, ProtectionDomain protectionDomain) throws ClassFormatError { - if (stack.getCallerClass() != DefineClassHelper.class) - throw new IllegalAccessError("Access denied for caller."); + try { + if (getCallerClass.invoke(stack) != DefineClassHelper.class) + throw new IllegalAccessError("Access denied for caller."); + } catch (Exception e) { + throw new RuntimeException("cannot initialize", e); + } return sunMiscUnsafe.defineClass(name, b, off, len, loader, protectionDomain); } |