如何动态更新JVM中的class文件
2010-11-27 23:33
309 查看
转载于:http://java.chinaitlab.com/Jvm/793556.html
在一个运营系统中,如果出现业务方法变更,而我们使用的应用服务器不支持热部署的话,那么重启可能是更新的唯一选择。目前多数应用服务器不支持热部署,包括生产模式下的weblogic。之所以说是生产模式,weblogic在开发模式下是支持这种动态更新的,即我们只要替换部署目录下的类文件,重新访问时可以看到新业务方法生效,而且即使在生产模式下,weblogic也能"支持"动态更新,但做法上比较麻烦,需要使用version信息控制应用,这个功能weblogic9就开始提供,但好像很少有客户这么用过。如果应用服务器不支持动态更新,我们有什么方法可以满足这种需求吗? 这就是我们这篇文章要讲述的,通过TI(更准确地说是JDI),我们可以实现。
为了能够正确的做到动态更新,我们首先需要attach到target JVM上.
连接上target JVM后,我们可以就可以利用vm提供的redefineClasses()将新的类文件注入到JVM中,替代原有的class信息。
1 public void reloadClasses(List toReloads){
2 Map toReloadMap = new HashMap();
3 for (Iterator iterator = toReloads.iterator(); iterator.hasNext();)
4 {
5 String toReload = (String) iterator.next();
6 InputStream is = VMDebugger.class.getClassLoader().getResourceAsStream(toReload.replace('.', '/') + ".class");
7 if (is == null) {
8 throw new RuntimeException("Class " + toReload + " is not found in current classpath");
9 }
10 List classes = vm.classesByName(toReload);
11 if (classes == null || classes.isEmpty()) {
12 throw new RuntimeException("Class: " + toReload + " is not found in target JVM");
13 } else {
14 ReferenceType ref = (ReferenceType) classes.get(0);
15 try{
16 toReloadMap.put(ref, toByteArray(is));
17 }catch(Exception e){
18 e.printStackTrace();
19 }
20 }
21 }
22 vm.redefineClasses(toReloadMap);
23 }
上面的方法有如下几个注意的地方:
1:确保要更新的类在当前classpath下(也就是启动VMDebugger的classpath)。
2:确保要更新的类在target JVM已被加载。
3:不同的VM实现上不一样,有的可能不允许动态更新,可以使用canRedefineClasses()
判断一下。
在一个运营系统中,如果出现业务方法变更,而我们使用的应用服务器不支持热部署的话,那么重启可能是更新的唯一选择。目前多数应用服务器不支持热部署,包括生产模式下的weblogic。之所以说是生产模式,weblogic在开发模式下是支持这种动态更新的,即我们只要替换部署目录下的类文件,重新访问时可以看到新业务方法生效,而且即使在生产模式下,weblogic也能"支持"动态更新,但做法上比较麻烦,需要使用version信息控制应用,这个功能weblogic9就开始提供,但好像很少有客户这么用过。如果应用服务器不支持动态更新,我们有什么方法可以满足这种需求吗? 这就是我们这篇文章要讲述的,通过TI(更准确地说是JDI),我们可以实现。
为了能够正确的做到动态更新,我们首先需要attach到target JVM上.
连接上target JVM后,我们可以就可以利用vm提供的redefineClasses()将新的类文件注入到JVM中,替代原有的class信息。
1 public void reloadClasses(List toReloads){
2 Map toReloadMap = new HashMap();
3 for (Iterator iterator = toReloads.iterator(); iterator.hasNext();)
4 {
5 String toReload = (String) iterator.next();
6 InputStream is = VMDebugger.class.getClassLoader().getResourceAsStream(toReload.replace('.', '/') + ".class");
7 if (is == null) {
8 throw new RuntimeException("Class " + toReload + " is not found in current classpath");
9 }
10 List classes = vm.classesByName(toReload);
11 if (classes == null || classes.isEmpty()) {
12 throw new RuntimeException("Class: " + toReload + " is not found in target JVM");
13 } else {
14 ReferenceType ref = (ReferenceType) classes.get(0);
15 try{
16 toReloadMap.put(ref, toByteArray(is));
17 }catch(Exception e){
18 e.printStackTrace();
19 }
20 }
21 }
22 vm.redefineClasses(toReloadMap);
23 }
上面的方法有如下几个注意的地方:
1:确保要更新的类在当前classpath下(也就是启动VMDebugger的classpath)。
2:确保要更新的类在target JVM已被加载。
3:不同的VM实现上不一样,有的可能不允许动态更新,可以使用canRedefineClasses()
判断一下。
相关文章推荐
- java中如何使用asm动态的生成或修改一个class文件以及asm的架构思想
- 如何在dos命令中查看class的jvm文件
- 如何获取java运行时动态生成的class文件?
- 如何在bat文件中查找jar包,动态设置classpath
- JVM加载class文件的原理机制
- JVM加载class文件的原理
- JVM加载class文件的原理机制
- 如何用Ext中的panel动态的加载js文件,我用的了autoLoad,并将其属性scripts设成了true,但还是不行
- 动态载入/删除/更新外部 JavaScript/Css 文件
- 如何让word里的统计图动态更新
- 如何利用Javap工具对.class文件进行查看
- 怎么使用jquery判断一个元素是否含有一个指定的类(class)另外如何给元素动态添加类
- 如何在eclipse中查看class文件
- 怎样更新jar包中的某个class文件??
- 如何解决xcode每次运行不clean就不更新资源文件的问题
- JVM加载class文件的原理机制?
- JVM加载class文件的原理机制
- JVM探索之路之Class文件结构解析(一):Class文件的格式与定义
- 水晶报表中如何动态加载图片(图片文件版本及数据库版本)
- Windows下的VIM - 如何自动在后台更新cscope数据库文件