aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/javassist/util/proxy/DefineClassHelper.java52
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);
}