【问题标题】:What does the sun.reflect.CallerSensitive annotation mean?sun.reflect.CallerSensitive 注释是什么意思?
【发布时间】:2014-05-02 20:05:29
【问题描述】:

@CallerSensitive注解上面的方法意味着什么?

例如,注解存在于Class的getClassLoader方法中

 @CallerSensitive
    public ClassLoader getClassLoader() {
    //
    }

【问题讨论】:

  • 开始here
  • 谢谢,但它有点技术性和混乱

标签: java class security reflection classloader


【解决方案1】:

根据我在 cmets 中链接的 JEP(也是 here),

调用者敏感方法根据类改变其行为 它的直接调用者。它通过调用发现其调用者的类 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 提出(并引入)了一个更简单的过程。

基本上@CallerSensitive注解被JVM使用

JVM 将跟踪此注解,并可选择强制执行 sun.reflect.Reflection.getCallerClass 方法可以不变量 仅当该方法标记为时才报告该方法的调用者 这个注释。

【讨论】:

  • 所以我知道在反射中识别调用者类很有用,对吧?而且由于 JVM 正在跟踪它,JVM 将无法识别任何在其方法中具有此注释的自定义类。所以它对核心库有用吗?
  • @AbhinavKumar 是的,这是我的理解。但我认为自定义类也可以使用它。你必须尝试一下。
  • 看到这个 sun-internal API 泄​​露到 JDK 的公共 API 中,我非常感到惊讶。为什么不是 java.lang.reflect.CallerSensitive 注释?
  • @LukasEder JEP 似乎只与 Open JDK 有关。我认为我在我浏览过的任何 javadoc 中都没有注意到 @CallerSenstive,尽管我看到了对 callersensitive 的引用。也许其他 JDK 的做法不同。我对这个过程了解不多。
  • @Boosha 这几乎只适用于 JVM。注意它所属的包是sun.reflect.***。这不是 JDK 中可用的包。我在回答中链接到的 JEP 指出,除其他外,它是一项安全改进,有助于更好地管理呼叫者。
【解决方案2】:

来自jdk.internal.reflect.CallerSensitive

注解@CallerSensitive 的方法对其调用类敏感, 通过 Reflection.getCallerClass 或类似的方式。

自 Java SE 9 起,等效值为 java.lang.StackWalker.getCallerClass

这实际上是 Java 1.0 和 1.1 版本的安全模型,它实现了一种 pauper 的链接器检查。这是一种连贯的方法,除了与反射有关的任何东西,但非常脆弱。另一方面,限制性更强的 Java 2 安全模型具有魔力,并未展示其工作原理。

@CallerSensitive 方法会根据调用它们的类改变行为。这总是令人惊讶,但 Java 2 堆栈检查安全模型也是如此。更糟糕的是,这些方法调用对于代表调用者工作的类特别有用,因此无论如何上下文都是错误的。

Secure Coding Guidelines for Java SE 覆盖该区域。

Java SE 9 中引入模块意味着一些细节发生了变化。

此外,如果使用Method.invoke 调用@CallerSensitive 方法,则getCallerClass 会忽略某些堆栈帧。在内部,JDK 使用“蹦床”ClassLoader 充当良性虚拟调用者。 java.lang.invoke.MethodHandle 复制Method.invoke 的问题。 AccessController.doPrivileged 方法也存在问题,规范的后果令人惊讶。

JEP 176: Mechanical Checking of Caller-Sensitive Methods 处理特定的@CallerSensitive jdk-internal 注释。指南中的方法列表由 FindBugs 插件生成,然后手动更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-16
    • 2018-01-02
    • 2012-06-21
    • 2019-05-10
    • 2010-11-29
    • 2017-01-28
    • 1970-01-01
    • 2021-05-04
    相关资源
    最近更新 更多