`

(转)jrebel使用

阅读更多

From: http://truemylife.iteye.com/blog/1140921

 

背景与愿景:开发环境下,tomcat对热布署的支持还不够全面,致使开发人员浪费大量时间在重起服务上。为了提高开发效率,决定引入Jrebel,它对热布署的支持相对比较全面。虽然Jrebel官方号称使用它不存在内存泄漏问题,但是占用一定的资源是肯定的,因此不考虑在正式环境下使用热布署。Jrebel实际上支持非常多中间件,除了Tomcat还包括Jetty、Resin、Weblogic等等,从理论上来讲,他跟中间件也没什么关系,但实际配置的时候还是会根据中间件有所不同,具体可以上官网查看,本文要讲的是tomcat+ eclipse+ spring+ struts2+ maven的环境。在使用Jrebel后,我们期望看到开发人员早上开机启动一次tomcat后就够了。本文的前置文章m2eclipse+tomcat实现应用布署,点击进入http://truemylife.iteye.com/blog/1669031

使用场景:Tomcat对热布署的使用场景是Servlet+JSP+JaveBean。如果项目含有其他框架时,其热布署效果就会大大降低,在与同事一同测试观察后发现:tomcat6在spring+struts框架下的项目,对java文件修改后的成功热布署概率偏低。由于概率太低,而且有无热布署成功不能确定,大部分开发人员修改类后不管什么情况直接选择重起,长此以往,浪费的时间积累起来不在少数。下面把tomcat和jrebel对热布署测试结果对比一下:

 

对比项

Jrebel

Tomcat

Class文件

绝大部分能热布署

小部分能热布署

Spring支持

改成用注释的方式后,可支持

不支持

Struts配置文件

支持

支持

页面相关文件

支持

支持

从对比可以看到,Jrebel最大的提升是对java类修改时,热布署大大提高;而对spring的支持实际上还是有限的,需要把IoC的实现改成使用注释的方式,而不能是配置的方式。如果你的工程的Spring已经是注释的方式,那就比较顺利,装好插件后,绝大部分情况下都能使用热布署了。如果你不是使用注释方式,那就麻烦了,要么全都改成注释方式,要么Jrebel对spring作用有限,看你自己的选择了。下面把已知Jrebel不能成功的热布署的情况作一列举:

1、替换了父类。

2、增加或删除了继承的接口。

3、Spring布署文件修改(如果改成注释方式,实际上spring只剩个别固定的第三方包的beans描述,比如数据库链接等)

4、web.xml,虽然jrebel和tomcat都支持web.xml修改的热布署,但是如果项目比较复杂,初始化工作较多的话,还是直接重起吧,直接热布署意义不大,而且重复初始化对于某些业务来说是会报错,所以建议有较复杂的初始化项目来说,还是直接重起得了。

 

Jrebel安装和使用

 

1、jrebel是商用软件,而且价格不扉,去下载个破解版吧,最新的破解版是4.0,如果网上找不到,请留下邮件。下载jrebel.jar到本地,比如放在d:\jrebel.jar

2、Eclipse window->preference->tomcat->JVM Settings,加入以下参数

-Drebel.spring_plugin=true 支持spring框架

-Drebel.aspectj_plugin=true 支持aspectj

-Drebel.struts2_plugin=true 支持strut2

-javaagent:D:\jrebel.jar 这里自行修改jrebel.jar正确的路径

-noverify

如果你要支持更多的框架,可以参考官网http://www.zeroturnaround.com/jrebel/features/frameworks/

如果你要了解更多的参数配置,可以参考官网

http://www.zeroturnaround.com/jrebel/configuration/

    jrebel支持监控多个目录下的classes、配置文件、jar包是否被修改,因此建议新建并配置rebel.xml文件,如果Eclipse安装了官网的jrebel plugin,那么可以从eclipse菜单里产生rebel.xml文件。以下是rebel.xml的简单手动配置:

<?xml version="1.0" encoding="UTF-8"?>

<application

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xmlns="http://www.zeroturnaround.com"

  xsi:schemaLocation="http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">

  <classpath>

    <dir name="E:\projects\cmac\target\classes"/>

    <dir name="E:\projects\cmac\target\test-classes"/>

  </classpath>

  <web>

    <link target="/">

      <dir name="E:\projects\cmac\src\main\webapp"/>

    </link>

  </web>

</application>

rebel.xml更详细配置说明参考官网(http://www.zeroturnaround.com/jrebel/configuration/)

3、此时启动tomcat,会发现如下错误信息

严重: Exception starting filter Struts2

java.lang.NoClassDefFoundError: Lorg/apache/velocity/app/VelocityEngine;

         at java.lang.Class.getDeclaredFields0(Native Method)

         at java.lang.Class.privateGetDeclaredFields(Class.java:2291)

         at java.lang.Class.getDeclaredFields(Class.java:1743)

         at com.opensymphony.xwork2.inject.ContainerImpl.addInjectors(ContainerImpl.java:102)

         at com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:84)

         at com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:82)

         at com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:155)

         at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

         at java.util.concurrent.FutureTask.run(FutureTask.java:138)

         at com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:81)

         at com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:121)

         at com.opensymphony.xwork2.inject.ContainerImpl$ConstructorInjector.<init>(ContainerImpl.java:333)

         at com.opensymphony.xwork2.inject.ContainerImpl$5.create(ContainerImpl.java:299)

         at com.opensymphony.xwork2.inject.ContainerImpl$5.create(ContainerImpl.java:298)

         at com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:155)

         at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

         at java.util.concurrent.FutureTask.run(FutureTask.java:138)

         at com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:81)

         at com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:121)

         at com.opensymphony.xwork2.inject.ContainerImpl.getConstructor(ContainerImpl.java:578)

         at com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:476)

         at com.opensymphony.xwork2.inject.ContainerImpl$7.call(ContainerImpl.java:517)

         at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:565)

         at com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:515)

         at com.opensymphony.xwork2.config.impl.LocatableFactory.create(LocatableFactory.java:32)

         at com.opensymphony.xwork2.inject.ContainerBuilder$4.create(ContainerBuilder.java:135)

         at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:49)

         at com.opensymphony.xwork2.inject.ContainerImpl$ParameterInjector.inject(ContainerImpl.java:447)

         at com.opensymphony.xwork2.inject.ContainerImpl.getParameters(ContainerImpl.java:462)

         at com.opensymphony.xwork2.inject.ContainerImpl.access$000(ContainerImpl.java:48)

         at com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:288)

         at com.opensymphony.xwork2.inject.ContainerImpl$2.call(ContainerImpl.java:117)

         at com.opensymphony.xwork2.inject.ContainerImpl$2.call(ContainerImpl.java:115)

         at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:558)

         at com.opensymphony.xwork2.inject.ContainerImpl.injectStatics(ContainerImpl.java:114)

         at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:495)

         at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:170)

         at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:55)

         at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:371)

         at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:424)

         at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:213)

         at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:273)

         at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:254)

         at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372)

         at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:98)

         at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4562)

         at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5240)

         at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5235)

         at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

         at java.util.concurrent.FutureTask.run(FutureTask.java:138)

         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

         at java.lang.Thread.run(Thread.java:619)

Caused by: java.lang.ClassNotFoundException: org.apache.velocity.app.VelocityEngine

         at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1676)

         at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)

         at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316)

         ... 53 more

竟然报出需要velocity相关包,那好吧,我的项目是用maven来做管理的,在pom.xml里加上相关依赖如下:

<dependency>

    <groupId>org.apache.velocity</groupId>

    <artifactId>velocity</artifactId>

    <version>1.7</version>

    </dependency>

    <dependency>

    <groupId>org.apache.velocity</groupId>

    <artifactId>velocity-tools</artifactId>

    <version>2.0</version>

</dependency>

再次重起tomcat后,一切正常,可以看到jrebel关键信息在console里输出:

JRebel: Directory 'E:\projects\cmac\target\classes' will be monitored for changes.

JRebel: Directory 'E:\projects\cmac\target\test-classes' will be monitored for changes.

JRebel: Directory 'E:\projects\cmac\src\main\webapp' will be monitored for changes.

4、如果你使用maven发布并启动tomcat,那么需要安装jrebel-maven-plugin。本文前面提到只是满足开发阶段而且启动tomcat方式不是使用mvn命令方式,因此不需要安装jrebel-maven-plugin。

 

Spring利用注释方式实现IoC

    现在大部分java项目有使用Spring框架,为了能使Jrebel更好的对Spring相关资源发生热布署作用,就得充分使用注释的方式实现依赖注入。这里对Spring实现注释方式作一下最简单的介绍,首先在applicationContext.xml里配置如下两行代码:

<context:annotation-config/> 

<context:component-scan base-package="*"/>

简单的说,以上的配置让spring支持了我们将要实现的注释依赖注入。以下以登录为实例,按action层、业务层、数据库操作层、PO层分别新建四个类:

LoginAction.java//struts action

UserServiceImpl.java//business layer

UserDaoImpl.java//dao layer

User.java //pojo

那么怎样通过注释方式进行调用的呢,首先给要被调用的类加上@Component注释,Spring为了区分不同层次的类,分别定义了以下四种注释

@Reposity

@Service

@Controller

@Component

目前阶段这四个注释实际上效果是一样的,我们约定如下:PO类如有需要使用@Reposity注释;Dao和Service使用@Service注释;Action使用@Controller注释;剩余分不出层次的类使用@Component注释。

如本例,action、service、dao分别加上注释

@Scope("prototype")

@Controller("loginAction")

public class LoginAction extends BaseAction{

}

@Service("userService")

public class UserServiceImpl implements UserService{

}

@Service("userDao")

public class UserDaoImpl extends BaseDao implements UserDao{

}

Scope注释默认是singleton,可以缺省。使用这四个标签时,如果不使用参数值,那么spring会按自己规范取名,比如LoginAction,使用@Controller()注释,默认取名为loginAction。取好了名,相当于在配置文件里配置了一组bean,接下来看怎么注入依赖,比如LoginAction要调用UserService,代码片段如下:

@Scope("prototype")

@Controller("loginAction")

public class LoginAction extends BaseAction{

@Autowired

Private UserService userService

}

就这么简单,添加xwork.xml配置,新加跳转页面,这些操作统统不用重起服务。

 

弹出Continue or Terminate疑问

    装上jrebel后,可以进入你的tomcat/conf/context.xml或server.xml,其中有一个参数reload=true,把它改成false。表示关闭tomcat自身的热布署,在eclipse里启动tomcat,修改了类,有时还是会弹出Continue or Terminate框,难道是个Bug?不得而知。不过有jrebel在不用担心,继续continue,会发现你的修改是有效的。只有碰到前面提到的不适合jrebel热布署的场景时,即使没弹出Continue or Terminate提示框,你也要自己重起服务。

 

Jrebel官方对热布署支持的场景列表(查看官网说明http://www.zeroturnaround.com/jrebel/features/)

 

Java EE Support

Jrebel

JVM Hot Swap

Time to reload

< 1s

< 1s

No memory leak

YES

YES

 

Changes to method bodies

YES

YES

Adding/removing Methods

YES

NO

Adding/removing constructors

YES

NO

Adding/removing fields

YES

NO

Adding/removing classes

YES

NO

Adding/removing annotations

YES

NO

Changing static field value

YES JRebel 3.0+

NO

Adding/removing enum values

YES JRebel 3.0+

NO

Changing interfaces

YES

NO

Replacing superclass

NO

NO

Adding/removing implemented interfaces

NO

NO

 

Skip builds for WAR directories

YES

YES

Skip builds for .WAR/.EAR class updates

YES

YES

Skip builds for .WAR/.EAR resource updates

YES

NO

Map multiple source dirs to one .WAR/.EAR target dir

YES

NO

Map classes and resources with include/exclude patterns

YES

NO

Map multiple source dirs with Ant-style patterns

YES

NO

Use system properties to make mapping machine-independent

YES

NO

Maven plugin

YES

NO

JSP EL changes

YES

NO

JSP Scriptlet changes

YES Enterprise Add-on

NO

EJB 1.x session bean interface changes

YES Enterprise Add-on

NO

EJB 2.x session bean interface changes

YES Enterprise Add-on

NO

EJB 3.x session bean interface changes

YES JRebel 3.0+

NO

JSF changes (Mojarra)

YES JRebel 3.0+

NO

JPA changes (Hibernate, EclipseLink, TopLink, OpenJPA)

YES JRebel 3.0+

NO

CDI changes (Weld)

YES JRebel 3.0+

NO

ResourceBundle

YES

NO

Spring Framework 2.x or later

YES

NO

Hibernate

YES JRebel 3.0+

NO

JBoss Seam 2.x or later

YES JRebel 3.0+

NO

Google Guice

YES

NO

Stripes 1.x or later

YES

NO

Apache log4j 1.2.x or later

YES

NO

Apache Struts 1.x

YES

NO

Apache Struts 2.x or later

YES

NO

Apache Tapestry4

YES

NO

Apache Velocity

YES

NO

Apache Wicket

YES

NO

CgLib

YES JRebel 3.0+

NO

Javassist

YES JRebel 3.0+

NO

Atlassian Confluence plugins

YES

NO

ClassWorlds

YES Beta

NO

Apache Felix

YES Beta

NO

Eclipse Equinox

YES Beta

NO

IntelliJ IDEA 7.x, 8.x plugins

YES Beta

NO

NetBeans plugins

YES Beta

NO

 

 

Jrebel对第三方框架支持对应表

查看官网http://www.zeroturnaround.com/jrebel/features/frameworks/

分享到:
评论

相关推荐

    IDEA JRebel热部署插件jar包

    此外,JRebel可能会增加内存使用,因此需要合理调整IDE和应用服务器的内存设置。 总结来说,IDEA的JRebel热部署插件是Java开发中不可或缺的工具,它通过实时代码更新极大地提升了开发效率,让开发者可以更专注于...

    Myeclipse2015+Jrebel热部署配置

    开发工具相互交流,现在较好的工具推荐用IDEA ,对应eclipse老粉不愿意转工具的可以拿去试试,提高工作效率还是有帮助

    开发环境JRebel热部署

    windows 操作系统 双击 jrebel2020 bin activategui.cmd 弹出 如下 界面第一个框 输入 样例: https :://jrebel.qekang. 738b776f 6cc9 4ac5 9574960a057392db红色部分不要变化 蓝色的 随便找个 guid 替换一下 。第...

    JrebelBrainsLicenseServerforJava-master.zip

    JRebel通常需要许可证才能在生产环境中使用,而这个项目可能是为了解决许可证管理的问题,例如创建自定义的许可服务器,使得团队成员可以无缝使用JRebel。 总的来说,这个项目是为了建立一个自托管的JRebel许可...

    不需要编译JAVA发布工具

    描述中提到的“博文链接:https://libin-bad.iteye.com/blog/617545”是一个指向特定博客文章的链接,虽然具体的内容没有提供,但可以推测这篇文章可能详细介绍了这种工具的使用方法、工作原理以及它如何帮助开发者...

    IDEA提高开发效率的7个插件(推荐)

    使用方法是:选中需要翻译的文字,使用快捷键翻译对象命名,最后使用多种语言的互译文字转语音自动选择字自动分词。 5. RestfulToolkit 插件 RestfulToolkit 插件可以根据接口搜索提供接口,可以测试实测根据接口...

    How to Get Started with IntelliJ IDEA as an Eclipse User

    他提到IntelliJ IDEA通过其插件JRebel,为Eclipse、NetBeans、IntelliJ IDEA提供了开发和调试功能。 #### 三、如何开始使用IntelliJ IDEA 接下来的章节描述了作为一个Eclipse用户,如何开始使用IntelliJ IDEA。内容...

    Lift Cookbook

    - 利用JRebel实现热部署。 - 配合Eclipse和IntelliJ IDEA开发环境。 - 查看lift_protoH2数据库。 - 使用最新版的Lift框架和Scala语言。 2. HTML与CSS - 测试与调试CSS选择器。 - 排序CSS选择器的操作顺序。 ...

    JAVA优化编程详解

    9. **热部署与动态编译**:书中还会涉及JRebel等热部署工具的使用,以及JIT(即时编译)的工作原理,帮助开发者在开发过程中快速迭代和优化代码。 10. **代码质量与可维护性**:优化不只是性能层面的,还包括代码...

    java exe4j

    ej-technologies是一家专注于开发Java工具的公司,除了exe4j,他们还提供了JProfiler(Java性能分析器)和JRebel(热部署工具)等其他知名产品。 **5. 注意事项** 在使用exe4j时,要注意版权问题,因为打包的Java...

    IDEA实用好用插件推荐及使用方法教程详解(必看)

    IDEA实用好用插件推荐及使用方法教程详解 IDEA是一个功能强大且流行的集成开发环境(Integrated Development Environment),它提供了许多实用插件来提高开发效率和质量。以下是IDEA实用好用插件推荐及使用方法教程...

    2 类加载子系统.md,学习代码

    在开发环境中,为了提高效率,开发者常常需要实现类的热替换,这就涉及到了类的重新加载技术,如JRebel等工具就提供了这样的功能。 9. **类加载与垃圾回收** 类实例的生命周期与类加载器密切相关,当一个类加载器...

    intellij-idea教程

    其中还包括了Java热部署插件JRebel的安装与使用,远程调试的配置方法,以及Alt+Enter快捷键的特殊用法。 在教程的最后部分,作者鼓励用户Fork教程的Gitbook版本,并根据个人喜好整理快捷键列表,导出为PDF文档以备...

    idea常用的插件.docx

    GsonFormat 是一款 JSON 转领域对象工具,旨在帮助开发者快速地将 JSON 数据转换为领域对象。该插件可以根据用户的需求生成相应的领域对象代码,从而提高开发效率。 12. String Manipulation String Manipulation ...

    idea jad插件反编译插件

    同时,jad支持与其他插件(如JRebel)的集成,以实现更高效的开发流程。 需要注意的是,虽然jad反编译出的代码通常可读性较高,但可能与原始源代码有所差异,特别是在处理复杂的字节码操作时。此外,反编译的代码不...

    java源代码编译java源代码编译

    - 插件如JRebel,可实现热部署,无需重启即可看到代码变更的效果。 7. **Java源代码的编译流程** 开发者通常会使用IDE或命令行进行源代码编译: - 创建源代码文件,例如`HelloWorld.java`。 - 使用`javac Hello...

    JAVA性能测试与调优案例

    8. **热部署优化**:使用热部署插件,如JRebel,减少应用更新对服务的影响。 9. **数据库连接池配置**:正确配置数据库连接池,如Druid、C3P0等,确保连接复用,减少数据库连接的创建和释放开销。 10. **负载均衡...

    性能调优专题-jvm类加载机制-performance-jvmclassloader.zip

    在开发环境中,为了快速测试和调试,可以使用如JRebel等工具实现类的热部署,无需重启JVM即可更新代码。了解这类工具的工作原理也能帮助我们优化类加载。 9. **模块系统与类加载** Java 9引入了模块系统,类加载...

    将之前基于SSM实现的教务管理系统改成SpringBoot+Mybatis实现.zip

    SpringBoot支持热部署插件,如Spring Loaded或JRebel,这使得在开发过程中修改代码后无需重启服务器,提高了开发效率。 7. **错误处理与日志记录**: SpringBoot提供了统一的错误处理机制,以及对各种日志框架的...

Global site tag (gtag.js) - Google Analytics