【问题标题】:Can Thread.setContextClassLoader set a different ClassLoader than returned by getCCL?Thread.setContextClassLoader 可以设置一个不同于 getCCL 返回的 ClassLoader 吗?
【发布时间】:2016-04-24 05:35:27
【问题描述】:

背景:

最近我实现了一段代码,它会为特定的操作设置合适的ClassLoader,并在操作完成后恢复原来的ClassLoader。

例如:

ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
try {
    Thread.currentThread().setContextClassLoader(specialCL);
    // do operation here that requires 'specialCL'
} finally {
    Thread.currentThread().setContextClassLoader(originalCL);
}

根据getContextClassLoader() 文档,返回的空值可能意味着两件事。 1) 系统 CL 或 2) 如果获取 sys CL 失败,则引导 CL。

返回:此线程的上下文 ClassLoader,或 null 表示系统类加载器(或者,如果失败,则为引导类加载器)

根据setContextClassLoader(Classloader cl) 文档,如果提供空 CL,则 1) 系统 CL 或 2) 如果设置 sys CL 失败,则引导 CL。

cl - 此线程的上下文 ClassLoader,或 null 表示系统类加载器(或者,如果失败,则为引导类加载器)


问题:

是否有可能使用上面的 try-finally-restore 编程模型,我最终会在线程上得到一个不同于我最初开始使用的 ClassLoader?

例如:

// start out with System CL

ClassLoader original = getContextClassLoader(); // returns null

Thread.currentThread().setContextClassLoader(otherCL);

Thread.currentThread().setContextClassLoader(original); // i.e. set to null
// setCCL() tries to set System CL... fails 
// setCCL() tries to set Bootstrap CL... succeeds

如果我们从 Bootstrap CL 开始,而当我们尝试使用 setContextClassLoader(null) 进行恢复时,系统 CL 也会恢复。两种情况都有可能吗?

【问题讨论】:

    标签: java classloader contextclassloader


    【解决方案1】:

    不,当您将上下文类加载器设置为null 时,它只是设置为null。所以它将继续使用它最初使用的任何类加载器。

    【讨论】:

    • 最初使用的类加载器的引用存储在哪里?在我的示例中,我将 ClassLoader 设置为其他内容,然后尝试恢复它
    • @aguibert 在 OpenJDK 实现中,Thread 类只包含一个名为 contextClassLoader 的字段。
    • 我不清楚的部分是故障转移机制是如何工作的,什么时候开始发挥作用?显然将一个字段设置为 null 永远不会失败,那么为什么 javadoc 描述它的行为呢?如果有人可以描述为什么提到故障转移,我会认为这是一个足够的答案
    • @aguibert 我认为您可能误解了“失败”这个成语。它只是意味着“如果那不可用”之类的东西,而不是任何事情的实际失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    相关资源
    最近更新 更多