名扬数据:加速Java应用开发2—加速项目调试启动速度

还是做不到如类的热部署/热替换。因此再写一篇关于热部署/热替换的文章。之前也有很多人介绍过这些知识,不过比较分散,写此篇的目的聚合它本文以HotSpot虚拟机为例。主要是通过一些技巧来提升启动速度。>

首先让我来看两个概念:热部署、热替换

热部署

即在容器运行过程中,重新加载类或重新加载整个项目。罕见的解决方案就是使用自定义ClassLoad

局部加载的示例:如JSPPlai框架;

重新加载整个项目的示例:如TomcatJetti默认都是定期检测class文件是否有修改,如果有,先卸载当前容器,再重新加载整个项目(reload

这种情况缺点很明显:只能重新装载整个类/整个项目,不能只替换类中的局部。

JSP热部署的介绍:

http://www.linuxidc.com/Linux/2013-05/83816.htm

Tomcat热部署的介绍:

http://www.94it.cn/a/jingxuanboke/2013/0501/4578.html

Play!框架:

http://mingj.iteye.com/blog/307238

热替换

热替换相对于之前的热部署的优势就是可以替换如方法体、增删方法/字段等类内部局部替换,而不是整个类。罕见的实现方式:HotSpot虚拟机的HotSwapHotSwap补丁、

HotSwap

只能热替换方法体。只要在eclips或idea等开发工具中开启debug模式即可使用。

HotSwap补丁 DCEVM

该补丁增强了HotSwap可以增加、删除类字段、方法和改变类的父类。也必须在debug模式下调试。具体使用可以参考如下文章,此就不重复了

hotswap 用户手册

DCE使用的问题及其解决方法

测试时使用的jdk1.6.0_25没有问题,不支持jdk1.6.0_26且我测试jdk7_13和jdk7_21没成功。官网介绍说其是基于JDK7-b102编译的估计我下的这两个版本不对。

java agent + Instrumentation

1Spring-Loaded

SpringSourc官网发布的用在Grails 2中,允许:添加/修改/删除 方法/字段/构造器。类型/方法/字段/构造器上的注解也允许修改,且也可以新增/删除/修改enum类型的值。

使用方式:

    -javaagent:<pathTo>/springloaded-{VERSION}.jar -noverify 

如在执行tomcat/jetti时的VM参数中指定如上配置即可。无需在debug模式下执行。如果使用的如idea可以按Ctrl+Shift+F9编译当前类/Ctrl+F9编译所有更改的类。

2Fakereplace 

类似于Spring-Load具体可参考其官网:

https://github.com/fakereplace/fakereplace 

https://github.com/fakereplace/fakereplace/wiki/How-It-Works

好处是支持一些框架:

    Seam 2

    Weld 基本集成)

    JSF

    Metawidget

    Hibernate 实际是如果实体修改了重启整个EMF也不是很快)

    Resteasy

具体使用也是VM参数中指定:

    -javaagent:/path/to/fakereplace.jar  

可以到如下地址下载jar包,或自己编译

http://repo.grails.org/grails/plugins-releases/org/fakereplace/fakereplace-dist/1.0.0.A lpha2/

其提供了一些配置,如:

    -javaagent:/path/to/fakereplace.jar=packages=com.mycompany.myclasses,log=trace   

    packages 需要热替换的包

    log 可选,支持trace,debug,info,error

    index-file fakereplac索引为的路径。Fakereplac第一次运行后存储这个文件以加速启动

    dump-dir 当热替换时,Dump类到这个目录,仅当开发Fakereplac时有用

    port Fakereplac监听的端口

俩的实现很类似,Spring-Load使用了CGLIB来实现代理,FakeReplac使用了Javassist来实现的

还有如Agent Smith不过N久没维护了 其实Plai框架也是使用了Instrument但是整个替换,所以没有归类过来。

以上的都有个缺点:如我写spring项目时,无法动态加载如@RequestMap配置,或动态加载配置文件。这些在强大的JRebel中都是支持的

JRebel

JRebel目前简单的最强大的热替换/热部署工具。但缺点是收费的而且方便宜。之前介绍的都是免费的首先大家可以看一下它支持的特性与JVM Hot Swap对比列表:

?

JavaEE支持 JRebel JVM Hot Swap

装载时间 <1s <1s

内存泄漏 无 无

改变类结构

 改变方法体  

   

 

添加/删除方法    

添加/删除构造器    

添加/删除字段    

 添加/删除类    

 添加/删除注解    

改变静态字段值     

添加/删除enum值     

改变接口     

替换父类     

添加/删除实现的接口     

即时构建  

跳过WA R目录的构建    

跳过.WA R/.EA R类更新构建    

跳过.WA R/.EA R资源更新构建    

映射多个sourc目录到一个.WA R/.EA R目标目录    

使用include/exclud模式映射类和资源 

使用Ant风格模式映射多个sourcd目录 

使用系统属性使映射机器无关 

Maven插件 

远程/云

通过HTTP进行应用更新 

JavaEE支持

JSP EL changes

JSP Scriptlet changes

EJB 1.x session bean interface changes

EJB 2.x session bean interface changes

EJB 3.x session bean interface changes

EJB 3.x: adding new EJB

EJB 3.x: adding new EJB reference

JSF changes Mojarra

Bean Validation support Hibernate Valid

JA XB annotation changes

JA X-RS changes RESTEasy, Jersey, CXF

JA X-WS support Metro, CXF

JPA  changes Hibernate, EclipseLink, TopLink, OpenJPA 

CDI changes Weld

框架支持

Spring Framework 2.x or later

Hibernate

JBoss Seam 2.x or later

Google Guice

Struts 1.x, 2.x

Wicket

Stripes 1.5 or later

检查完整的框架支持列表

代理支持

CgLib

Javassist

OSGi支持

A pache Felix

Eclipse Equinox

从如上列表看到其不是一般的强大。

接下来看看如何使用(以IDEA 为例)

1首先点击如下图所示的运行,然后点击Edit Configuration...

2弹出的窗口中输入如下图所示的jrebel.jar位置

类似于之前的javaag配置。

3启动后,当修改类后,请按Ctrl+F9重新编译。然后再执行顺序即可看到变化。

4Eclips内嵌tomcat配置:

使用起来是非常简单的注意:如果使用web容器如tomcatjetti请禁用其reload如jetti可以配置

<scanIntervalSeconds>0</scanIntervalSeconds> 或者 <reload>manual</reload>

JRebel也提供如EclipsIDEA Maven插件,其实没必要上插件,直接配javaag就很简单。还可以配置

如果有朋友想开启/禁用某些框架/JavaEE支持,可以通过添加VM参数,如下所示开启/关闭:

 -Drebel.spring_plugin=true

   -Drebel.aspectj_plugin=true

   -Drebel.struts2_plugin=true

   -Drebel.hibernate_plugin=true

   -Drebel.jackson_plugin=true

   -Drebel.log4j-plugin=true

完整的框架支持列表

还可以通过配置一个rebel.xml来进行选择性构建:

http://zeroturnaround.com/software/jrebel/how-to-configure-rebel-xml/

更多配置请参考其官方的JRebel手册。

此就介绍完了见到所有热部署/热替换实现方式,大家还有什么好的方式欢迎补充。