最近尝试使用maven的overlay来合并war包,这样有一个好处,就是可以把公共框架部分的jsp/js/css等抽取出来,得到一个公共的war工程,然后其它系统只要依赖这个war工程就可以,自己系统的jsp/css/js可以分离出来,更容易管理。
但是这样一个改变却导致我几天睡不好。因为我之前一直使用的tomcat7-maven-plugin来开发和调试程序,使用overlay后发现tomcat最新的插件都不支持overlay,它找不到依赖的war包里面的文件,网上找了些资料,发现都解决不了,不得已决定换插件。
首先我想到了jetty插件,尝试了一下,最新版本是9.3.7,发现可以支持overlay。而且比tomcat快,欣喜不已,可惜好景不长,没高兴一会就发现问题了。jetty居然不支持jstl和@WebServlet注解,我觉得不可能啊,网上一通找资料,把文档http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html看了几遍,没找到任何配置和jstl和servlet3.0有关,试了一天后,觉得不行,换一个吧,于是换成resin.
结果resin更坑, 看官方资料http://wiki3.caucho.com/Maven2 很简单,按这个配置,结果使用4.0.1以下版本全报错说描述文件不对,无法启动。换成4.0.14以上版本可以启动,但是最后会报错说com.caucho.maven.MavenRun里面找不到contextRoot, 看了下jar里面的确没有这个属性,但是网上找不到任何这方面的资料,唯一找到的也是一个人遇到这个问题没有解决。我就奇怪了,难道没人用这个插件?没人遇到这个问题?一度我认为是maven的版本问题,可以我是3.*的版本,试了几个也没解决。最后无解,resin放弃。
就是要吐血的时候,今天又试了下jetty,发现了一个问题,一开始我以为是tomcat本身有一些依赖包而jetty没有,所以我试着把下面的依赖全加到插件下
结果依然不行。
然后我看到了一篇文章 http://gimgen1026.iteye.com/blog/155354
servlets 2.4(我没记错的话JSP 2.0出来之后的第一个版本),这个版本的isELIgnored默认设置为false。所以使用web.xml里用web-app_2_4.xsd声明的时候在JSP页面不用特意声明。
下面是官方Documention中isELIgnored Attribute的详解:
The isELIgnored Attribute
• Format
– <%@ page isELIgnored="false" %>
– <%@ page isELIgnored="true" %>
Purpose
– To control whether the JSP 2.0 Expression Language
(EL) is ignored (true) or evaluated normally (false).
• Notes
– If your web.xml specifies servlets 2.3 (corresponding to
JSP 1.2) or earlier, the default is true
• But it is still legal to change the default—you are permitted
to use this attribute in a JSP-2.0-compliant server
regardless of the web.xml version.
– If your web.xml specifies servlets 2.4 (corresponding to
JSP 2.0) or earlier, the default is false
也就是说2.4以前要自已在jsp上加<%@ page isELIgnored="false" %> ,而以后的版本不用了。
我看了下我的web.xml,终于找到问题了,原来少写了version="2.5", 加上后jetty就正常了。
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
后来又看了cargo,感觉这个不错,可以使用大部分servlet容器来运行,像jetty/tomcat/jobss/resin/glassfish等,有机会要试试。不过感觉配置稍复杂一点,但是功能更强大。有时间也要试一下。可参考 http://blog.youkuaiyun.com/steveguoshao/article/details/38469713
另外 这个博客有一系列的maven插件的使用文章,挺不错
http://www.cnblogs.com/edwardlauxh/archive/2010/07/15/1918557.html
补充一下:
后面使用jetty还发现了几个问题,
1. 启动时报错说spring-web的web-fragment.xml重复加载,一个是在maven的本地库中, 一个是在target目录中,在web.xml中增加metadata-complete="true" 可解决,但会导致@webServlet失效,应该是设置为true后就不扫描注解了吧,最后解决办法是在插件中增加allowDuplicateFragmentNames 为true.
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.7.v20160115</version>
<configuration>
<scanIntervalSeconds>5</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
</webApp>
<httpConnector>
<port>80</port>
</httpConnector>
</configuration>
</plugin>
2. 如果web项目A是基类项目,里面包含了spring的配置文件,而web项目B是运行的web项目,会依赖A工程,并使用overlay合并war包,在使用jetty插件调试的时候还是需要把spring的配置文件,web.xml等从A项目拷贝到B项目,不然加载不到。
3. jetty每次热部署都会删除tmp目录,但是我这边发现spring, shiro的一些包启动后会被加载到JVM,导致tmp目录删除不了,不能重启动,在webApp下增加配置_persistTmpDir到true,可以不删除tmp目录,而是新增一个。不过jetty每次拷贝所有jar包到tmp目录太慢了,相对而言还是tomcat插件启动更快。
4. webApp下面的extraClasspath属性一配置就导致资源文件都找不到,未解决。
5. scanTargetPatterns 配置 scanTargetPattern可以每次一改动就触发热部署。