5月23日 西安 OSC 源创会开始报名啦,存储、虚拟机、Docker 等干货分享
我在平时工作中部署Web项目到测试服务器上的Tomcat时用的是Hudson。Hudson本身已经跟SVN、Git、Maven集成并且支持添加各种插件。但如果使用Hudson,我需要配置两个任务:一个任务负责打包项目成WAR,另外一个任务负责部署打包好的WAR包到目标服务器的Tomcat上。虽然任务只需要配置一次,但每次修改代码提交后,都得切换到浏览器点Hudson构建任务页面上的Build Now按钮,然后还得跳转到另一个页面观察是否有报错,然后再点击执行相应的部署任务。烦不胜烦,偶然发现Tomcat Maven插件支持直接打包并部署项目到Tomcat中,尝试一番后终于搞定,总结于此。
网上关于这个主题的文章也不少,过程也大同小异,但本文除了过程外还想记录下我期间踩过的坑和关于这种部署方案的建议。
1、准备工作
下载安装并配置好Tomcat和Maven。
准备好一个Maven Web项目。
2、Maven部署Web项目到Tomcat的配置
2.1、配置Tomcat角色
Maven自动部署实际上调的是Tomcat安装目录下的manager功能。而为了能正常访问http://localhost:8080/manager页面,我们需要修改$TOMCAT_HOME/conf目录下的tomcat-users.xml:
1
2
3
4
5
6
7
8
9
|
<
tomcat-users
>
<
role
rolename
=
"tomcat"
/>
<
role
rolename
=
"manager"
/>
<
role
rolename
=
"manager-gui"
/>
<
role
rolename
=
"manager-script"
/>
<
role
rolename
=
"admin-gui"
/>
<
user
username
=
"tomcat"
password
=
"tomcat"
roles="tomcat,manager,
manager-gui,manager-script,admin-gui" />
</
tomcat-users
>
|
2.2、修改pom.xml增加Tomcat Maven插件
我使用的Tomcat7,pom.xml中增加如下配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<
properties
>
<
project.build.sourceEncoding
>UTF-8</
project.build.sourceEncoding
>
<
spring.version
>3.2.2.RELEASE</
spring.version
>
<
finalName
>web-loab</
finalName
>
</
properties
>
<
build
>
<
plugins
>
<
plugin
>
<
groupId
>org.apache.tomcat.maven</
groupId
>
<
artifactId
>tomcat7-maven-plugin</
artifactId
>
<
configuration
>
<
url
>http://localhost:8080/manager/text</
url
>
<
server
>tomcat</
server
>
<
username
>tomcat</
username
>
<
password
>tomcat</
password
>
<
path
>/${finalName}</
path
>
</
configuration
>
</
plugin
>
</
plugins
>
</
build
>
|
上面username、password来自tomcat-users.xml。server是Tomcat服务器名称。path是访问应用的路径。url指定Tomcat管理页路径。
2.3、修改Maven的settings.xml
在$USER_HOME/.m2目录下找到settings.xml,添加server节点:
1
2
3
4
5
6
7
|
<
servers
>
<
server
>
<
id
>tomcat</
id
>
<
username
>tomcat</
username
>
<
password
>tomcat</
password
>
</
server
>
</
servers
>
|
上面的username、password依然与tomcat-users.xml中相同,id与2.2中的server相同
2.4、部署项目到Tomcat
先确保Tomcat服务器已经启动,然后cd到项目根目录,运行下面的命令:
1
|
mvn clean tomcat7:redeploy
|
部署成功,如下:
然后我们就能在Tomcat安装目录的webapps目录下找到新部署的WAR包。
初次部署用的是tomcat7:deploy命令,重新部署可以用tomcat7:redeploy命令(推荐统一用这个),Tomcat Maven插件支持的命令包括:run、shutdown、run-war-only、exec-war、standalone-war-only、deploy、standalone-war、undeploy、run-war、redeploy等。
3、踩过的坑
光看上面的过程,似乎非常顺畅,但世上的事总是不会那么顺利的。下面列举几个我踩过的坑。
3.1、Windows系统下,redeploy过程无法删除旧项目的目录
报错信息在$TOMCAT_HOME/logs下的catalina日志文件中,如下:
1
2
3
|
信息: Undeploying context [/web-loab]
十月 11, 2014 3:52:26 下午 org.apache.catalina.startup.ExpandWar deleteDir
严重: [D:\tomcat\apache-tomcat-7.0.56\webapps\web-loab\WEB-INF] could not be completely deleted. The presence of the remaining files may cause problems
|
大概是因为Tomcat还在使用这个目录,无法删除,必须修改$TOMCAT_HOME/conf/context.xml:
1
|
<
Context
antiJARLocking
=
"true"
antiResourceLocking
=
"true"
>
|
3.2、Servelt.class offending
这个问题应该不属于本文主题范畴了,但可能因为这个导致Web项目启动起来却无法访问,报错信息如下:
1
2
|
十月 11, 2014 3:46:29 下午 org.apache.catalina.loader.WebappClassLoader validateJarFile
信息: validateJarFile(D:\tomcat\apache-tomcat-7.0.56\webapps\web-loab\WEB-INF\lib\servlet-api-6.0.29.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/servlet/Servlet.class
|
原因是webapps目录下的某个Web项目的WEB-INF/lib目录下有servlet-api.jar,删除之,并在pom.xml中指定servelt-api.jar的scope为provided:
1
2
3
4
5
6
|
<
dependency
>
<
groupId
>org.apache.tomcat</
groupId
>
<
artifactId
>servlet-api</
artifactId
>
<
version
>6.0.29</
version
>
<
scope
>provided</
scope
>
</
dependency
>
|
3.3、版本问题
确保Web项目的Java Build Path使用的JDK版本、Java Compiler的编译JDK版本以及Project Facets里的Java版本一致。
如果用的Tomcat6,则pom.xml中配置tomcat6-maven-plugin,如果用的tomcat7则用tomcat7-maven-plugin。或者默认用tomcat-maven-plugin。
4、有关使用Tomcat Maven插件部署项目的一些建议
这种方案能够实现持续快捷部署。但它有一些局限性:
-
要求从本地开发环境能直接访问Tomcat服务器所在网段
-
不能保留历史部署包
因此初步建议只在开发环境使用这种部署方式,并且结合SVN、Git等版本控制软件做两个内部约定:
-
所有可部署版本代码都必须先签入一个名为deploy-xx的分支,xx表示当前可部署版本,deploy分支代码必须保证是可以部署的代码,然后切到deploy-xx分支再部署项目
-
以后增加了新功能,则需新建另一个deploy分支,并增大版本号。这样可以利用版本控制软件帮我们保留各个历史可部署代码(解决了上面提到的第二个局限性)。尤其是多个项目集成时,最好保证每一次集成时各个项目的deploy分支带的版本后缀相同。这样可以方便各个项目代码集体回滚