JVM的深入理解:由一次Quartz的定时任务引发的“A cannot cast t
由Quartz框架引发的“A cannot cast to A”的问题起因与问题描述向新开的项目中添加定时任务,部署集群,添加了热加载(springboot-dev-tools),发现在转型时候出现了A cannot cast to A”的问题。自己怎么可能不认识自己???排查走起!!! 排查类确实是同一类,问题会出现在哪里呢?我们可以想到,类加载器不同会导致“我不是我”的问题,所以打印debug走起! ? 知识回顾?类加载器机制
sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); ... scl = l.getClassLoader(); AppClassloader是sun.misc.Launcher类的内部类,Launcher类在new自己的时候生成AppClassloader实例并且放在自己的私有变量loader里: loader = AppClassLoader.getAppClassLoader(extclassloader); 值得一提的是sun.misc.Launcher类使用了一种类似单例模式的方法,即既提供了单例模式的接口getLauncher()又把构造函数设成了public的。但是在ClassLoader中是通过单件模式取得的Launcher 实例的,所以我们写的每个类加载器得到的AppClassloader都是同一个AppClassloader类实例。 springboot-dev-tools可以参考<a href = "https://blog.csdn.net/isea533/article/details/70495714">Spring DevTools 介绍一文,其中最关键的一句话就是 重启功能是通过使用两个类加载器实现的。 对于大多数应用程序,此方法运行良好,但有时可能会导致类加载问题。 默认情况下,IDE中的任何打开的项目都会使用“restart”类加载器加载,任何常规.jar文件将使用“base”类加载器加载。 ? 解决问题? 在项目 /resource/META-INF目录下(如果没有就创建一个)创建 restart.include.mapper=/mapper-[w-.]+jar restart.include.pagehelper=/pagehelper-[w-.]+jar restart.include.shiro=/shiro-[w-.]+jar 这里其实是 添加 jar 包到 restart 类加载器中 = 后面是具体的 jar 包名称,或正则表达式 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |