Skip to content

Commit

Permalink
[#171] Allow running on JDK 8 and possibly on JDK 7 as well. Fixes #171
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Jun 22, 2018
1 parent dfce4e4 commit 92ee53b
Showing 1 changed file with 43 additions and 9 deletions.
52 changes: 43 additions & 9 deletions src/main/javassist/util/proxy/DefineClassHelper.java
Expand Up @@ -51,8 +51,12 @@ final class ReferencedUnsafe
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,
Expand All @@ -64,14 +68,40 @@ Class<?> defineClass(String name, byte[] b, int off, int len,
}
}
}
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");
Expand All @@ -91,8 +121,12 @@ public Class<?> defineClass(String name, byte[] b, int off, int len,
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);
}
Expand Down

0 comments on commit 92ee53b

Please sign in to comment.