IT忍者神龟之用 jreloader 动态重新加载改变的类而不用重启 JVM

在 Tomcat 中可以配置 reloadable="true" 做到类改变后,Tomcat 重新加载。其实这个过程大约也是当 Tomcat 发现有改变的类会重新启动一个新的应用程序重新加载所有的类来服务于新的请求,只是不需要你手动的去执行 shutdown.sh(.bat),再 startup.sh(.bat)。这种方式对于古老的 jsp 程序完全能从容以对,因为 web.xml 里几乎没什么随应用一起启动且耗时长代码;但当下是框架横行,web.xml 中随应用一起启动的程度可谓是争先恐后的,所以仅仅依赖
reloadable="true" 是满足不了需求的。每改一个类(无论是改动了方法体中的代码还是变动了类的结构,准确的说是动了 WEB-INF/classes 目录中的任何文件) 你都可能就会在

Jan 28, 2011 7:19:42 PM org.apache.catalina.core.ApplicationContext log

INFO: Initializing Spring root WebApplicationContext

这一步上等上半天,况且对于 reloadable="true" 对于类结构的改动是无动为力的,像实现了不同的接口,继承了不同的类,或者增删了方法或属性的时候,Tomcat 必须是 shutdown,然而再 startup 的。

这样的频繁重启对于调试是一种煎熬,所以希望能找到一个工具,能在类改动的时候不需要重新启动当前应用,当然不希望重启 Tomcat 了。能实现此功能的工具有 JavaRebel和 jreloader,其中前者是收费的,后者是开源的,不过后者实际上也不错。

这里介绍下后者在 Eclipse WTP  Tomcat 环境中怎么配置使用。

当前版本是 jreloader-0.4.zip,其中有
jreloader.jar 和 jreloader-src.zip,再就是非常简单且足够的 INSTALL.txt 文件:


01

02

03

04

05

06

07

08

09

10

11

You
need only to add a couple of vm arguments, as in the example below:

java
-noverify -javaagent:c:\tools\jreloader.jar -Djreloader.dirs=c:\project\target\classes com.foo.Main

or

java
-noverify -javaagent:c:\tools\jreloader.jar -Djreloader.dirs=c:\project\target\classes -jar foo.jar

If
you have multiple modules, you can add more than one class dir:

 -Djreloader.dirs=c:\project\target\classes,c:\project2\target\classes,c:\project2\target\classes

和 JavaRebel 一样通过 javaagent 来控制的,用 -Djreloader.dirs 来监测可能用变化的 classpath,可以逗号分隔的多个。对于 WEB 程序我们只需监测 /WEB-INF/classes 目录的。其实不管任何程序,我们只要想办法把 -javaagent 这个参数设置进去,你自己改 catalina.bat(.sh) 也行。

现在说 Eclipse WTP 中如何给创建的 Tomcat 服务器设置上面的 JVM 参数,Eclipse 中进到 Tomcat 配置的 Overview 页,点击 Open launch configuration, 弹出 Edit Configuration 窗口,再到 Arguments 标签页中,VM arguments: 输入框中加上:

-noverify -javaagent:D:\jreloader-0.4\jreloader.jar -Djreloader.dirs=D:\workspaces\j2ee\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\TestJavaWeb\WEB-INF\classes

说明:我把 jreloader.jar 放在 d:\jreloader-0.4 目录中的,WTP 插件通常把应用发布在 D:\workspaces\j2ee\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\TestJavaWeb 像这样的位置中,只要 Djreloader.dirs 指向到该应用发布后的目录中 WEB-INF/classes 子目录。每改动一个类,WTP 都会发布到这个 classes 目录中去,所以你要关心的是这个实际运行时加载类的地方。

除了上面的 VM arguments 之外,还必须把 Tomcat 里该应用的 reloadable 设为 false,阻止 Tomcat 去管理,而完全由 jreloader 去承担类的热加载。

Eclispe WTP 对 Tomcat 的配置会反应到 D:\workspaces\j2ee\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\conf\server.xml 中,所以直接改这里面的 server.xml,把 reloadable 改为 false 后仍然会被覆盖为 true。

不过,我们还有个办法,就是在项目的 META-INF 目录中创建 context.xml 文件,在其中写上:

<Context antiResourceLocking="false" privileged="true" reloadable="false"/>

这里面的配置届时会被 WTP 合并到 D:\workspaces\j2ee\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\conf\server.xml 文件中的。

现在可以尝试一下了,启动 Tomcat,首先看到:

+---------------------------------------------------+

| JReloader Agent 0.4                               |

| Copyright 2008,2009 Antonio S. R. Gomes           |

| See LICENSE-2.0.txt details                       |

+---------------------------------------------------+

如果有一个类改动后,控制台下会看到:

D:\workspaces\j2ee\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FootnotedPro\WEB-INF\classes\cc\unmi\struts\model\ElementItem.class

[JReloader:INFO ] Reloading class cc.unmi.strtus.model.ElementItem

马上就可以在浏览器中看到效果了,再也不用一遍遍的看 Tomcat 或其他框架(想想亚运会上其他国家被拉着一遍遍忍受中国国情形) 的脸色了:

Jan 28, 2011 7:19:42 PM org.apache.catalina.core.ApplicationContext log

INFO: Initializing Spring root WebApplicationContext

对于启动的独立应用程序,应该没什么好多说的,加启动参数:-noverify -javaagent:c:\tools\jreloader.jar -Djreloader.dirs=c:\project\target\classes,就行,这对于长时间的服务程序,或守护程序也是有用的。

相比于 JavaRebel 来说,从调试窗口中看到 jreloader 并没有去在字节码上作很多文章,看到的类名仍然是原来的类名,并且可一样方便的断点调试。

时间: 2024-08-02 17:53:18

IT忍者神龟之用 jreloader 动态重新加载改变的类而不用重启 JVM的相关文章

JS获取图片的缩略图,并且动态的加载多张图片

找了好多资料也没有找到该死的ie的解决办法,最后放弃了ie <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>js获取缩略图</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <st

nginx php动态编译加载模块.

#Nginx动态编译加载模块步骤 #查看目前Nginx版本及编译模块 #[[email protected] ~]# /opt/app/lnmp/nginx-1.12.0/sbin/nginx -V #nginx version: nginx/1.12.0 #built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) #built with OpenSSL 1.0.2k  26 Jan 2017 #TLS SNI support enabled #c

AutoSharedLibrary -- 基于模板元编程技术的跨平台C++动态链接加载库

基于模板元编程技术的跨平台C++动态链接加载库.通过模板技术,使用者仅需通过简单的宏,即可使编译器在编译期自动生成加载动态链接库导出符号的代码,无任何额外的运行时开销. ASL_LIBRARY_BEGIN(TestLib) ASL_SYMBOL(Proc_test1, test1, false) ASL_SYMBOL(Proc_test2, test2, true) ASL_LIBRARY_END() TestLib theLib; try { theLib.Load("./1.so"

esri-leaflet入门教程(5)- 动态要素加载

esri-leaflet入门教程(5)- 动态绘制图形 by 李远祥 在上一章节中已经说明了esr-leaflet是如何加载ArcGIS Server提供的各种服务,这些都是服务本身来决定的,API脚本只是非常简单的调用.但如果要做一列的地图交互操作或者动态渲染等,那就必须使用地图区域跳转.查询结果渲染.动态添加图形等多种交互手段.而这些交互手段基本上离不开一些非服务类型的数据加载,我们可以将其成为动态要素.动态要素一般是在页面端进行动态绘制的. 动态要素这一说法并不是ArcGIS 或者leaf

java动态加载指定的类或者jar包反射调用其方法

序言 有时候,项目中会用到java动态加载指定的类或者jar包反射调用其方法来达到模块的分离,使各个功能之间耦合性大大降低,更加的模块化,代码利用率更高.模式中的代理模式就用到java的这一机制.下边就让我们通过代码来看看如何实现此功能. 代码详细 package loadjarclass; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoad

Bootstrap tab页的动态ajax加载

要实现这样的功能,点击tab导航ajax动态加载页面,当加载过之后,点击则不再重新加载,直接显示原来加载的页面. tab页面代码: <!-- Nav tabs --><ul class="nav nav-tabs" role="tablist" id="maintab">  <li class="active"><a href="#tab1"  onclick='s

Silverlight项目笔记7:xml/json数据解析、MVVM下实现多级树形结构TreeView、忽视引用类型导致数据绑定错误、通过流或动态空间加载图片、虚拟目录设置、silverlight安全机制引发的问题、WebClient缓存问题

涉及的内容主要有: 1.xml/json数据解析 2.多级树形结构TreeView 3.忽视引用类型导致数据绑定错误 4.通过流或动态空间加载图片 5.虚拟目录设置 6.silverlight安全机制引发的问题 7.webclient缓存问题 1.xml/json数据解析 (1)xml数据解析 使用WebClient获取数据,获取到的数据实例化为一个XDocument,使用XDocument的Descendants(XName)方法获得对应节点的数据集合,再通过Element这个方法对数据集合进

Linux程序动态库加载优化

作者:zhanhailiang 日期:2014-10-26 linux程序动态库加载流程简介 linux从程序(program或对象)变成进程(process或进程),简单说来需要经过三步: fork进程,在内核创建进程相关内核项,加载进程可执行文件: 查找依赖的.so,逐一加载映射虚拟地址: 初始化程序变量: 如下例通过strace查看pwd命令执行过程: [root@~/wade/codeReview/learningc]# strace pwd execve("/bin/pwd"

Java_动态重新加载Class机制

Java动态重新加载Class 项目中使用到了动态重新加载Class的机制,作用是让一些代码上线之前可以在线上环境测试一下,当然,这是非常不好的测试机制,我刚来的时候也为这种机制感到惊讶—怎么可以在线上环境运行测试代码!后来经过了解,这么做的原因有以下两个: 有些代码没有办法在本地进行测试,本地没有线上的环境 我们弱到连测试机都没有(这是重点) 既然我们连测试机都没有,那么我就觉得我们的项目其实也没有想象中的重要,这么测就这么测吧~~     之前对ClassLoader没啥概念,google到