]> source.dussan.org Git - javassist.git/commitdiff
[#171] Allow running on JDK 8 and possibly on JDK 7 as well. Fixes #171 204/head
authorChristian Beikov <christian.beikov@gmail.com>
Fri, 22 Jun 2018 07:03:55 +0000 (09:03 +0200)
committerChristian Beikov <christian.beikov@gmail.com>
Fri, 22 Jun 2018 07:06:01 +0000 (09:06 +0200)
src/main/javassist/util/proxy/DefineClassHelper.java

index 4d6c9f9d1598f2b5d39befb847548a454a199241..3869111892d29c44d667f1d36ad7114283e542d4 100644 (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);
             }