Browse Source

Merge pull request #204 from beikov/issues/171

[#171] Allow running on JDK 8 and possibly on JDK 7 as well. Fixes #171
tags/rel_3_23_1_ga
Shigeru Chiba 5 years ago
parent
commit
f85a72b883
No account linked to committer's email address
1 changed files with 43 additions and 9 deletions
  1. 43
    9
      src/main/javassist/util/proxy/DefineClassHelper.java

+ 43
- 9
src/main/javassist/util/proxy/DefineClassHelper.java View File

@@ -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);
}

Loading…
Cancel
Save