`
argan
  • 浏览: 126190 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

实现增强的java class hotswap (二) 面临的问题

阅读更多

要实现自己的class reload机制,首先需要明白我们面临什么样的问题,首先,虚拟机中使用到的Class都是由各种ClassLoader装载进来的,而绝大部分程序的开发者都不需要关心这个过程,我们面临的第一个问题就是需要将class装载这个过程拦截下来,让所有的需要reload 的class的装载都经过我们的机制,我们才有机会去执行我们的reload机制,因此我们需要拦截系统的ClassLoader,在class装载的时候实现自己的逻辑

 

jdk提供JVMTI(JVMDI,JVMPI),可以从底层的虚拟机里获取几乎所有虚拟机里发生的事件,我们可以通过捕获这些事件,加以处理,来实现我们的目的,但是操作jvm内部的事件必须非常小心,否则非常容易造成虚拟机工作不正常,甚至崩溃。同时,要使用JVMTI这些底层的api,我们需要使用c/c++来实现功能,对于我们要实现的目的来说,太复杂了点,而且,对于我来说,几乎没正经写过c/c++代码,因此这条路不予考虑。

 

从java5开始,jdk开始提供一种新的机制来帮助我们实现这种功能,java agent 可以方面的帮助我们实现这一功能,我们可以通过简单的实现一个包含premain方法的类就可以作为java agent在虚拟机里执行,具体可以参考文档 。因此,我们可以通过实现一个agent,在系统起来的时候通过instrmentation修改系统的ClassLoader,加入我们自己逻辑的代码来拦截class装载的过程。注意,这里只能修改已有方法的方法体,例如修改findClass方法,在这些方法体里可以加入调用我们真正逻辑的类的方法调用,来实现自己的class装载测律。

 

对于jdk 1.4及以前的版本呢?没有更好的办法,只能实现将系统的ClassLoader等相关类进行静态的enhance,然后通过 bootclasspath在rt.jar之前加载进来,用自己的类挡住系统自己的类,来实现我们的逻辑,除了这个拦截的方式不一样以外,其他的逻辑处理和jdk5没有区别,因此以后的讨论不需要区分jdk版本的区别。

 

class装载的过程由我们控制了,但是由于jvm自身的限制,对于已经装载进虚拟机的类(准确的说是装载进某一个ClassLoader的类),是无法做太大的修改的,只能修改方法的代码段,对于类结构是无法更改的,因此,我们面临的又一个问题就是如何巧妙的绕过这个限制。

 

其实想想也简单,既然已经装载进来的类无法做很大的修改,那我们就不让他装载进来!

 

嘿嘿,干活了,下次再说。邪恶吧?!

4
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics