Maven插件实现热部署,支持Tomcat和Jetty插件

Maven是一个非常优秀的工具,在Maven出现之前,一个项目如果业务很多,很复杂,整个项目就非常庞大。这会造成如下几个问题:
1、项目后期维护成本大,新加一个需求需要全盘考虑会不会影响其他的业务逻辑;
2、开发效率低下,改动一个Java文件需要重启Tomcat (Jetty等)服务器 ,重新编译整个项目,编译会花去一定的时间,程序员开发的时间会大大减少;
3、所有的业务代码和非业务代码紧密耦合在一起,无法拆分;
4、jar文件冲突,不同的业务代码依赖jar的版本无法做到统一。

Maven出现后,很好的解决了上述问题。使用Maven后,一个大的项目被拆分成小的模块,这样程序员可以专注于某个模块,开发效率大大提高。同时程序员改了某个模块后,只需编译这个模块,这样减少了编译时间。Maven也很好的管理jar,所有的jar可以通过自己构建私服统一管理,冲突问题得以解决。

写到这里也许你会问,Maven似乎已经实现分模块编译和打包的功能,实现了热部署,还要在Maven上做什么文章?确实,Maven解决了“热部署”。一般情况下不需要再做什么文章了,分模块已经大大的提高了开发效率。如果一个项目拆分成几个模块后,模块不能继续再分了(模块分的越多也不是很好,不便于管理),但是模块还是很大,这时候有点问题了!!

于是就有人提出,JVM每次编译Java文件只编译.class文件改动的文件,这样会提高JVM编译效率。JRebel插件是其中一种,可以监控哪些Java文件被修改过,原理就不叙述了,可以百度相关文章阅读。

本文只讨论Maven插件( Tomcat + JRebel)实现Web项目热部署(增量部署)功能。其他插件如Jetty也可以实现热部署,Maven的配置类似,本人也成功使用Jetty插件实现热部署,鉴于篇幅原因,这里就不在赘述。开发中选择Tomcat还是Jetty依项目而定,不过 一般推荐使用Jetty插件,Jetty比Tomcat 更轻量级,大多数情况下Jetty完全可以满足需求。需要注意的是,JBoss插件的支持不是很好,目前本人未能成功用JBoss插件实现分模块打包,如果你实现了用JBoss插件分模块打包,并可以正常的运行项目,欢迎分享给大家。

好了,开始进入正题,Tomcat + JRebel 插件实现热部署。

1、配置编译插件:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.7</source>
        <target>1.7</target>
    </configuration>
</plugin>

2、配置打源码插件(可选项):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>2.1.1</version>
    <configuration>
        <attach>true</attach>
    </configuration>
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

3、配置Tomcat 插件,关闭Tomcat 本身的热部署功能:
<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
        <port>8888</port>
        <path>/uums-web</path>
        <uriEncoding>UTF-8</uriEncoding>
        <!-- 监控web.xml文件 -->
        <contextFile>${basedir}/src/main/webapp/WEB-INF/web.xml</contextFile>
        <useTestClasspath>false</useTestClasspath>
        
        <webAppConfig>
            <contextPath>/${project.artifactId}</contextPath>
            <extraClasspath>  
                ../uums-common/target/classes;  
            </extraClasspath>
        </webAppConfig>
        
        <scanTargets>  
            <scanTarget>../uums-common/target/classes</scanTarget>
        </scanTargets>
        
        <scanTargetPatterns>
            <scanTargetPattern>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.java</include>
                </includes>
            </scanTargetPattern>
            <scanTargetPattern>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                </includes>
                <excludes>
                    <exclude>**/*.xml</exclude>
                </excludes>
            </scanTargetPattern>
        </scanTargetPatterns>
        <!-- 关闭tomcat自身的热部署 -->
        <scanIntervalSeconds>0</scanIntervalSeconds>
        <webAppSourceDirectory>${basedir}/src/main/webapp</webAppSourceDirectory>
    </configuration>
</plugin>
  
4、JRebel插件Maven配置:
<plugin>  
    <groupId>org.zeroturnaround</groupId>  
    <artifactId>jrebel-maven-plugin</artifactId>  
    <version>1.1.5</version>  
    <executions>  
        <execution>  
            <id>generate-rebel-xml</id>  
            <phase>process-resources</phase>  
            <goals>  
                <goal>generate</goal>  
            </goals>  
        </execution>  
    </executions>  
    <configuration>  
        <rebelXmlDirectory>${basedir}/src/main/webapp/WEB-INF/classes</rebelXmlDirectory>  
    </configuration>  
</plugin>

5、指定编译后文件的存放路径。
因 为Tomcat 默认src/main/webapp为 web应用的根目录,而maven compile目标后的默认classpath在target文件夹下,就造成jrebel.xml无法兼顾Tomcat 默认的是webapp中的 classes为web应用的根目录,而Maven默认是target目录,所以需要修改该Maven的默认classes目录。
<outputDirectory>${basedir}/src/main/webapp/WEB-INF/classes</outputDirectory>

6、在Eclipse 里下载JRebel插件:
点击Help->Eclipse Marketplace,下载JRebel for Eclipse插件。



7、配置jrebel.jar的路径
点击Windows->Prefrences->JRebel->Advanced,在JRebel agent里指定下载好的jrebel.jar的路径。



8、配置VM参数:



使用maven命令: tomcat7:run,启动Tomcat ,出现如下信息,则说明JRebel配置成功。



在uums-web的/WEB-INF/classes目录下生成了一个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 http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">

	<classpath>
		<dir name="F:/workspace/uums/uums-web/src/main/webapp/WEB-INF/classes"></dir>
	</classpath>

	<web>
		<link target="/">
			<dir name="F:/workspace/uums/uums-web/src/main/webapp"></dir>
		</link>
	</web>

</application>



启动Tomcat ,在浏览器地址栏输入 http://localhost:8888/uums-web/,显 示默认页面,这时修改LoginAction.java和LoginDaoImpl.java文件,发现只加载LoginAction.java和 LoginDaoImpl.java文件,不需要重启Tomcat 重新编译整个模块。实现了只编译修改的.class文件,大功告成!


上 面似乎没有任何问题,但是,问题还是出现了,比如修改了uums-common模块(uums-common是uums-web依赖的模块)里的Java 文件,发现并没有reload修改的那个文件。上述配置只实现了reload uums-web模块修改的Java文件,其依赖的模块被修改并不能被reload,需要重新编译uums-common模块。这个问题一直困扰了我很 久,经过查阅资料和不断地测试,终于实现了不用重新编译uums-common模块也可以实现reload修改的Java文件,只需在uums-web模 块的pom.xml文件添加如下的配置即可。注意,如果uums-web依赖多个模块,则需要在每个依赖的模块的后面加上“;”。
<webAppConfig>
    <contextPath>/${project.artifactId}</contextPath>
    <extraClasspath>  
        ../uums-common/target/classes;  
    </extraClasspath>
</webAppConfig>

<scanTargets>  
    <scanTarget>../uums-common/target/classes</scanTarget>
</scanTargets>


重启Tomcat,这次修改uums-common模块的Java文件,发现可以被reload,至此热部署得以实现。
由于本人能力有限,问题在所难免,恳请各位批评指正!


==================================全文完==================================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值