sun.reflect.CallerSensitive 注释是什么意思?
上述方法的注释暗示了什么?@CallerSensitive
例如,注释存在于类的getClassLoader方法中。
@CallerSensitive
public ClassLoader getClassLoader() {
//
}
上述方法的注释暗示了什么?@CallerSensitive
例如,注释存在于类的getClassLoader方法中。
@CallerSensitive
public ClassLoader getClassLoader() {
//
}
根据我在评论中链接的JEP(也在这里),
对调用方敏感的方法根据其直接调用方的类改变其行为。它通过调用该方法来发现其调用方的类。
sun.reflect.Reflection.getCallerClass
如果你看一下实施Class#forName(String)
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true,
ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
,你注意到它使用的是 Reflection.getCallerClass()。
如果我们看看这种方法
返回调用此方法的方法的调用方的类,忽略 与 关联的帧及其实现。
java.lang.reflect.Method.invoke()
@CallerSensitive
public static native Class getCallerClass();
在此 JEP 之前,问题似乎是,如果调用方敏感方法是通过反射而不是直接调用的,则必须有一个复杂的过程来识别实际的调用类是什么。如果通过反射调用该方法,则存在问题。使用 提出(并引入了)一个更简单的过程。@CallerSensitive
基本上,注释由JVM使用。@CallerSensitive
JVM 将跟踪此注释,并(可选)强制实施不变量,即该方法只能在使用此方法标记该方法时报告该方法的调用方。
sun.reflect.Reflection.getCallerClass
从jdk.internal.reflect.CallerSensitive
@CallerSensitive注释的方法通过其反射.getCallerClass或通过某些等效项对其调用类敏感。
等效项是从 Java SE 9 开始的。java.lang.StackWalker.getCallerClass
这实际上是Java版本1.0和1.1的安全模型,它们实现了一种pauper的链接器检查。这是一种连贯的方法,除了与反射有关的任何东西,但非常脆弱。另一方面,限制性更强的Java 2安全模型是神奇的,并没有显示其工作原理。
@CallerSensitive
方法根据调用它们的类改变行为。这总是令人惊讶的,但Java 2堆栈检查安全模型也是如此。更糟糕的是,这些方法调用对于代表其调用方工作的类特别有用,因此上下文无论如何都是错误的。
Java SE 的安全编码指南涵盖了这一领域。
Java SE 9中模块的引入意味着一些细节已经改变。
此外,如果使用某些堆栈帧调用该方法,则 将被 忽略。在内部,JDK使用“蹦床”作为良性的假呼叫者。 复制 了 的问题。这些方法也存在问题,规范的后果令人惊讶。@CallerSensitive
Method.invoke
getCallerClass
ClassLoader
java.lang.invoke.MethodHandle
Method.invoke
AccessController.doPrivileged
JEP 176:调用方敏感方法的机械检查处理特定的jdk内部注释。指南中的方法列表由 FindBugs 插件生成,但随后手动更新。@CallerSensitive