[spring-projects/spring-boot]将 JMX 端点的类加载器设置为应用程序类加载器

2024-04-29 256 views
7

相关和修复:#12088

在调用端点之前,将 JMX 端点的线程类加载器设置为最初用于加载上下文的类加载器。

前:

--- Class Loaders
getClass().getClassLoader(): java.net.URLClassLoader@4ac20dd2
currentThread().getContextClassLoader(): sun.misc.Launcher$AppClassLoader@18b4aac2
ClassUtils.getDefaultClassLoader(): sun.misc.Launcher$AppClassLoader@18b4aac2
---

后:

--- Class Loaders
getClass().getClassLoader(): java.net.URLClassLoader@4ac20dd2
currentThread().getContextClassLoader(): java.net.URLClassLoader@4ac20dd2
ClassUtils.getDefaultClassLoader(): java.net.URLClassLoader@4ac20dd2
---

测试代码(使用 start.spring.io 中的示例应用程序,包括网络和执行器):

@Component
@JmxEndpoint(id = "classloader")
public class JmxClassloaderEndpoint {
    @WriteOperation
    public void someOperation() {
        System.out.println("--- Class Loaders");
        System.out.println("getClass().getClassLoader(): " + getClass().getClassLoader());
        System.out.println("currentThread().getContextClassLoader(): " + Thread.currentThread().getContextClassLoader());
        System.out.println("ClassUtils.getDefaultClassLoader(): " + ClassUtils.getDefaultClassLoader());
        System.out.println("---");
    }
}

回答

7

构建失败似乎是随机的,与此更改无关,有人可以重新触发构建吗?

0

关闭并重新打开以触发新的构建。

0

我想这曾经和特拉维斯一起工作过。似乎没有与 Concourse 合作过。

2

我已在 Concourse 上手动触发了新的构建,但我不确定它正在构建正确的更改。日志中有一些与 git 相关的错误。

3

有这方面的新闻或兴趣吗?

8

@Dav1dde 有。我不久前看过你的提案,不太喜欢它,但我没有什么可提供的。我得先再挖一点。

1

@snicoll 谢谢你!

你说得对,感觉很黑客。希望我更新它以便类加载器来自BeanClassLoaderAware而不是getClass().getClassLoader()

7

恐怕这不会有太大改变。一旦调用该方法,就切换当前线程的类加载器而不恢复先前的实例,这对我来说绝对是错误的。我只会将其作为最后的选择。

7

哦,那不是问题,实际上有一个版本可以恢复它。 (这也是我们现在工作中所做的)。我今晚会更新这个,看看你是否更喜欢这个。

7

抱歉,我的意思是这个提案对我来说看起来不太好(至少应该恢复类加载器)。

1

现在更新并恢复类加载器(如果未设置 bean 类加载器,例如在测试中,则无操作)。我个人也不喜欢这个解决方案,但我想不出更好的解决方案,如果您能想到什么,请告诉我,我可以相应地更改 PR。

1

谢谢@Dav1dde,这确实是对情况的非常好的总结。我会花更多的时间来处理它,并在完成后在这里报告。

8

FWIW,除了SecurityException我刚才评论的之外,我认为我们应该做出这个改变。

8

今晚晚些时候我会更新。

2

分支已更新,我添加了一些注释,我不确定这种方式是否正常并适合 spring 代码库。

0

@Dav1dde 感谢您对 Spring Boot 的第一个贡献。这已合并到2.0.x和中master