文档章节

如何为Eclipse上的Tomcat配置代码热替换(Hot Code Replacement )

依然菜刀
 依然菜刀
发布于 2017/08/25 09:38
字数 2274
阅读 25
收藏 0
点赞 1
评论 0

本博客会引导你配置Eclipse的Tomcat的热代码替换(也叫做hotswap debugging)

  • 什么是“热代码替换”
  • 什么是“JPDA”、“JDI”
  • 基于JPDA的Tomcat的配置
  • “JPDA”的局限性——Catch
  • 改进方案1:DCEVM
  • 改进方案2:JRebel

什么是“热代码替换”

“热代码替换”(Hot Code Replace,以下简称HCR)就是当你正在调试web程序的时候,jvm允许让你修改的Java代码立刻生效,而不用重启程序,HCR是Java Platform Debugger Architecture(JPDA)的一部分(它包含很多东西,比如我们的远程调试也是),HCR在现代JVM中都有支持。

看下如下的代码:

public class Sample {
  public static void main(String[] args) {
    String foo = "unchangeable";
    foo += blah();
    System.out.println(foo);
  }
  
  public static String blah() {
    String bar = "bar";
    bar += "blah";
    return bar;
  }
  
}

如果你正在Eclipse中调试这段代码,你可以修改它,在线的,而不用重启程序,比如,在blah方法的第二行打一个断点,然后调试程序,程序会在bar +=那行挂起,然后修改把字符串“blah”改为“quz”,保存文件,程序会继续运行,当前行会跳到blah方法的第一行,并且会以新的代码运行。

什么是“JPDA”、“JDI”

简单来说,Java Platform Debugger Architecture(JPDA)就是Java提供的一套用于开发Java调试工具的规范,任何的JDK实现都需要实现这个规范。

JDI是这套调试工具提供的API接口,JDI的API在com.sun.jdi包下,相当于是JDI的接口规范了。除了JDK自带的实现外,我在HotSpot的SA中也发现了一个实现。他俩的实现分别是在com.sun.tools.jdi包下和sun.jvm.hotspot.jdi包下

正是因为有了他们,你才可以像上面那么玩儿。

“JPDA”的局限性——catch

你在基于Tomcat运行的web程序中也可以这么玩儿,但是会有一些问题:

“Hot Code Replace Failed”

Some code changes cannot be hot swapped into a running virtual machine, such as changing method names or introducing errors into running code. The current target virtual machine was unable to replace It is safe to continue ...

然后给你4个按钮:continue、details、terminate、restart

这个提示应该很眼熟吧,这个叫做Catch。然后刚刚修改的代码也没有生效,连行号都不对了。

什么是Catch?

当我们在使用HCR的时候还是有很多限制的:

  1. HCR只能替换方法里面的代码
  2. 不能修改类签名(类名、继承类、实现接口)、方法签名(方法名和参数列表)、成员变量
  3. 不能新增类
  4. 特殊的方法调用不能修改,例如main方法,通过反射调用的方法(这些统称为“stack frames”)

如果你修改了,那么上面的错误提示就出来了。

基于Tomcat的Web项目配置

配置基于Tomcat的web项目

项目配置,我们通常可以按照如下的步骤将web项目部署到Eclipse的Tomcat中:

  1. 下载EE版的Eclipse
  2. 在设置中配置Tomcat。打开设置,找到Servers,然后
  3. 创建Dynamic Web Project
  4. 在Servers视图中new Server
  5. 右击创建好的Tomcat,选择Add And Remove...,将项目部署到Tomcat中
  6. 以Debug模式启动Tomcat

禁用Auto Reloading

发布到Tomcat中的项目,默认都是开启Auto Reloading的,为了更好地使用JPDA功能,请按照如下步骤禁用Tomcat的Auto Reloading

  1. 双击Servers View中的Tomcat。
  2. Services View应该是默认就有的,万一没有或者被关闭了,你可以通过如下方式打开它:菜单:window→show view→services。
  3. 切换到Modules,选中要修改的project,然后点击edit,去掉“Auto Reloading Enabled”前面的勾。

为什么禁用Auto Reloading

Auto Reloading是一种tomcat用来实现不使用JPDA情况下支持java类热替换的。在这种模式下,Tomcat使用java中的classloaders来卸载并重新加载class,当它重新加的时候,tomcat会尝试重新初始化你的系统,重新启动那些在web.xml中标记为load-on-startup的servlet。

结果是,当你的项目里面有很多的启动代码时,这么做并不会给你节省时间,例如:如果你的启动代码需要初始化Hibernate的数据库缓存,Spring的依赖注入配置等等,你将会花费更长的时间,甚至比重启tomcat还要长。

更加坑爹的是,被自动加载的程序有时候会变得很奇怪,而且非常容易出现PermGen的内存溢出,这些都是因为频繁的卸载、重新加载类引起的。当出现这个错误的时候,重启tomcat通常可以解决这个问题。如果你即使只花费了5分钟来解决重新加载的问题,你也被坑了,因为本来你指望通过reload来做到比重启tomcat更省时间的,结果并没有。

通过禁用这个“Auto Reloading”来改为使用JPDA的代码热替换,你获得了更为可靠的代码热替换。

禁用“Auto Reloading”但是启用“Auto Publishing”

根据上面说的,你应该知道如何禁用“Auto Reloading”了吧,虽然“Auto Reloading”会导致JPDA工作不正常,但是tomcat的配置页的“Overview”Tab页有另一个设置叫做“Automatically publish when resources change”,它默认是手气的,你可以点击按钮展开它;当你禁用了“Auto Reloading”以后,这个“Auto Publishing”请确保已经打开。

为了了解两者的区别,我们需要先了解一下Eclipse的WTP是如何工作的。当你在Eclipse了里面创建了一个“Server”以后,Eclipse会在你的workspace中创建一个虚拟的Tomcat目录,这个目录里面完整包含了:conf、logs、temp、webapps、works这些目录,当你配置了这个服务,其实你就告诉了Eclipse去哪儿找tomcat的运行目录,但并不会使用webapps目录里面任何你的配置文件或者数据,在Eclipse启动tomcat的时候,它将虚拟目录的位置通过启动启动参数的方式传递给了jvm。

“发布(Publishing)”意思就是说将你全部的代码复制到这个虚拟目录中,包括:JSP、jar包,配置文件,动态生成的配置等等。

如果你禁用了这个发布功能,那么你就需要右击Server View里面你的Tomcat,然后点击“Publish”菜单了,而且每次你保存代码都要这么来一遍,更加好的是,如果你开启了“Auto Publishing”,Tomcat可以自动就支持JSP的自动重新加载(可以不用JPDA就可以支持)。

找到Tomcat虚拟目录tmp0

很多时候,看下tomcat虚拟目录的里面都有什么东西对我们代码开发是非常有帮助的。通过如下方式我们可以找到tomcat虚拟目录:通过双击Servers View中的Tomcat,在弹出的页面中找到Service Locations,我们就可以看到了,通常,虚拟目录在:.metadata/.plugins/org.eclipse.wst.server.core/tmp0,最后一个0是会变的,多个Tomcat的时候会从0开始往上涨。

这个.metadata目录在你的workspace中(你可以通过如下方式找到workspace的位置:菜单:FileSwitch Workspace默认的那个就是你当前的workspace),或者,启动Eclipse的时候让你选择的workspace就是你当前的workspace。

在这个虚拟目录中,你可以看到所有Eclipse自动创建的目录,看看conf目录下的server.xml,检查一下work目录下jsp自动生成的java文件,webapps里面肯定是空的,因为Eclipse使用的是wtpwebapps目录。

改进方案:

上面说了,JPDA有很多的局限性,但是国外牛人的能力是强大的,我们可以通过如下的方式来让我们的代码开发更加高效!

DCEVM

这个是github上的一个开源项目,是国外的一个牛人基于OpenJDK7的源码重新编写了其中代码热替换部分实现的jvm,通过将我们默认的Hotspot JVM替换为此JVM,就可以自动实现类名修改、方法名修改等一些JPDA不支持的代码热替换了。

JRebel

JavaRebel 是一个代码热替换系统,它要比HCR好一点 (可能好很多),也能弥补DCEVM对很多web框架不支持的不足。

有了JavaRebel,你可以在不重启Tomcat地情况下增加、删除方法和类,而且多个project同时运行时不会串,更好的是,它支持对很多框架都加入了支持(Spring、Struts、Jboss等等),比如,你正在基于Spring做代码开发,新增了一个Controller类或者增加了一个方法(有@RequestMapping),通常情况下,你需要重启Tomcat来让其生效,但是如果你的Eclipse安装了JavaRebel,那么当你保存的时候,Controller的信息就全部重新加载了,直接在浏览器就可以访问对应的URL!

唯一的缺憾就是,它收费,每个开发人员每年需要支付149美元,当然了,在天朝,嘿嘿(*^__^*) 。

 

 

© 著作权归作者所有

共有 人打赏支持
依然菜刀
粉丝 5
博文 1
码字总数 2274
作品 0
广州
Eclipse JEE中Server Options追踪

今天用Mercurial将<workspace>ServersTomcat v6.0 Server at localhost-config以及 <workspace>.metadata.pluginsorg.eclipse.wst.server.core纳入版本控制,监控了Eclipse JEE在修改Server ......

cyper ⋅ 2012/09/28 ⋅ 0

如何打造一个令人愉悦的前端开发环境(四)

原文链接 此文是我同事写的,搭建Express结合Webpack。以下是正文,后面我会附上我的解读 Express 结合 Webpack 实现HMR 本篇文件主要讲结合 Webpack 和 Express 实现前后端热更新开发,如果...

乖小鬼YQ ⋅ 2017/11/29 ⋅ 0

Webpack HMR 原理解析

Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过...

冉四夕 ⋅ 2017/11/08 ⋅ 0

Eclipse Maven Tomcat的利用配置

1.事先准备 m2eclipse插件中其实内嵌了Maven,但个人更偏向于用独立的Maven(可以自由选择版本啦,偶尔可以在命令行中跑Maven命令啦)。 下载Apache Maven:http://maven.apache.org/,关于环...

躺着的S ⋅ 2013/08/03 ⋅ 4

分享:一篇webpack配置基础绝好文章

Webpack是目前基于React和Redux开发的应用的主要打包工具。我想使用Angular 2或其他框架开发的应用也有很多在使用Webpack。 当我第一次看到Webpack的配置文件时,它看起来非常的陌生,我非常...

⋅ 01/10 ⋅ 0

webpack热更新原理WebSocket与EventSource

开发环境页面热更新早已是主流,常见的需求如赛事网页推送比赛结果、网页实时展示投票或点赞数据、在线评论或弹幕、在线聊天室等,都需要借助热更新功能,才能达到实时的端对端的极致体验。 ...

筱飞 ⋅ 04/16 ⋅ 0

webpack(2)——配置项详解

引子 昨天有关 Webpack 笔记也是有许多人喜爱的,所以今天再接再厉汇总了第二篇笔记,欢迎各位指点不足之处。 之后的笔记应该会记录一些实际开发了,希望在这个周末内彻底入门 Webapck。 we...

AdityaSui ⋅ 05/18 ⋅ 0

一步步构造自己的vue2.0+webpack环境

前面vue2.0和webpack都已经有接触了些(vue.js入门,webpack入门之简单例子跑起来),现在开始学习如何构造自己的vue2.0+webpack环境。 1.首先新建一个目录vue-wkdemo,这是我们的项目目录。...

邹君安 ⋅ 2017/05/09 ⋅ 0

IDEA开发Spring调试时自动部署的问题

以前用Eclipse jee的时候,修改了java代码,是可以自动部署的。现在使用了idea的时候,如果服务器使用tomcat的话,可以进行热部署,但是如果换了weblogic的时候,修改了java代码,界面就会出...

周文冬 ⋅ 2014/03/29 ⋅ 1

maven实现多模块热部署

一、背景 基于maven的项目工程都会按模块划分,每个模块最终形成一个jar包,那么每次对模块的修改就需要重新打包,这样的工作重复而繁琐,以前的热部署解决方案都是只针对web模块的修改,如能...

小咔蹭 ⋅ 2013/09/28 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Cube、Cuboid 和 Cube Segment

1.Cube (或Data Cube),即数据立方体,是一种常用于数据分析与索引的技术;它可以对原始数据建立多维度索引。通过 Cube 对数据进行分析,可以大大加快数据的查询效率 2.Cuboid 在 Kylin 中特...

无精疯 ⋅ 27分钟前 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 29分钟前 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 39分钟前 ⋅ 0

云计算的选择悖论如何对待?

人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云计算为...

linux-tao ⋅ 42分钟前 ⋅ 0

我的第一篇个人博客

虽然这是个技术博客,但是,我总是想写一些自己的东西,所有就大胆的在这里写下了第一篇非技术博客。技术博客也很久没有更新,个人原因。 以后自己打算在这里写一些非技术博客,可能个人观点...

Mrs_CoCo ⋅ 43分钟前 ⋅ 0

Redis 注册为 Windows 服务

Redis 注册为 Windows 服务 redis 注册为 windows 服务相关命令 注册服务 redis-server.exe –service-install redis.windows.conf 删除服务 redis-server –service-uninstall 启动服务 re......

Os_yxguang ⋅ 43分钟前 ⋅ 0

世界那么大,语言那么多,为什么选择Micropython,它的优势在哪?

最近国内MicroPython风靡程序界,是什么原因导致它这么火呢?是因为他功能强大,遵循Mit协议开源么? 错!因为使用它真的是太舒服了!!! Micropython的由来,这得益于Damien George这位伟大...

bodasisiter ⋅ 46分钟前 ⋅ 0

docker 清理总结

杀死所有正在运行的容器 docker kill $(docker ps -a -q) 删除所有已经停止的容器(docker rm没有加-f参数,运行中的容器不会删掉) docker rm $(docker ps -a -q) 删除所有未打 dangling 标...

vvx1024 ⋅ 57分钟前 ⋅ 0

关于学习

以前学车的时候,教练说了这样的一句话:如果一个人坐在车上一直学,一直学,反而不如大家轮流着学。因为一个人一直学,就没有给自己留空间来反思和改进。而轮流着学的时候大家下来之后思考上...

mskk ⋅ 今天 ⋅ 0

压缩工具之gzip-bzip2-xz

win下常见压缩工具:rar zip 7z linux下常见压缩工具:zip gz bz2 xz tar.gz tar.bz2 tar.xz gzip 不支持目录压缩 gzip 1.txt #压缩。执行后1.txt消失,生成1.txt.gz压缩文件 gzip -d 1.txt....

ZHENG-JY ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部