/** * Returns the class this method was called 'framesToSkip' frames up the caller hierarchy. JDK * used to have {@link sun.reflect.Reflection#getCallerClass(int)} until jdk 1.8 build 87. So we * have to resort to slow stack unwinding. * * <p>NOTE: <b>Extremely expensive! Please consider not using it. These aren't the droids you're * looking for!</b> */ @SuppressWarnings("JavadocReference") @Nullable public static Class getCallerClass(int framesToSkip) { int frames = framesToSkip; StackTraceElement[] stackTrace = new Throwable().getStackTrace(); String className = null; for (int i = 1; i <= frames; i++) { if (i >= stackTrace.length) { break; } StackTraceElement element = stackTrace[i]; className = element.getClassName(); if (className.equals("java.lang.reflect.Method") || className.equals("sun.reflect.NativeMethodAccessorImpl") || className.equals("sun.reflect.DelegatingMethodAccessorImpl")) { frames++; continue; } if (i == frames) { break; } } if (className == null) { // some plugins incorrectly expect not-null class too far up the caller chain, // so provide some not-null class for them className = ReflectionUtil.class.getName(); } try { return Class.forName(className); } catch (ClassNotFoundException ignored) { } ClassLoader pluginClassLoader = PLUGIN_CLASS_LOADER_DETECTOR.fun(className); if (pluginClassLoader != null) { try { return Class.forName(className, false, pluginClassLoader); } catch (ClassNotFoundException ignored) { } } LOG.error( "Could not load class '" + className + "' using classLoader " + ReflectionUtil.class.getClassLoader() + "." + (stackTrace[1].getClassName().equals("com.intellij.openapi.util.IconLoader") ? " Use getIcon(String, Class) instead." : "")); return null; }