一次坑死爹的Java项目tomcat7部署异常

刚接手一台开发机,已经使用过比较久的时间,可能前后经历的人比较多,所以环境比较杂,不熟悉。场景是这样的,我的本地环境是OSX10.9的Java7,代码都在本地开发,已经部署测试完毕,使用的是tomcat7版本。然后eclipse使用ant编译成war包后准备服务器部署,问题来了。

问题1

部署后启动tomcat,程序不能运行,Unsupported major.minor version 51.0,大体意思是提示编译问题,然后查看开发机Java环境,发现是1.6,本地修改eclipse的Java Compiler的Compiler compliance level为1.6即可。

问题2

修改后继续部署,发现还是无法启动,理论上来说已经不存在编译问题。不过考虑本机确实没有Java1.6环境,装一个也未尝不可,所以开始尝试在OSX10.9.2上安装JDK6,然后就开始了Google、百度,无果,Oracle官网不提供JDK1.6的安装版,在低版本的OSX中JDK1.6是自带的,到Apple开发者网站上也没找到JDK1.6安装程序,只有升级包。

这里提示下,如果你也遇到类似问题,别去想着在OSX上安装JDK1.6了,如果不是线上版本更换成本太大,建议换Java7以上版本。

总之,妄想在最新版的OS X上安装低版本JDK不成(低版本的OS X自带JDK6),又回到问题上来。

【请注意】,这里还没有解决编译版本问题,有的场景按照问题1描述更改后可以,有些不可以,待本文最后再说如何解决编译问题。

问题3

先抛开问题2,查看Tomcat各个日志,发现另一个错误:

1
java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addFilter

Google下,网上的解决方案为Tomacat7启动报错-org.apache.catalina.deploy.WebXml addFilter

1
在Tomacat7的context.xml文件里的<Context>中加上<Loader delegate="true" />

修改后仍无法启动,这时候已经开始狂躁了 -_-!! 继续查日志。

问题4

catalina.out中发现另一个错误SEVERE: Error listenerStart,隐藏极深,只有一行,仅此一句,无其他提示,尼玛啊。继续google,找到这个Tomcat启动报Error listenerStart错误

不过并没有按照正文里操作,而是在日志localhost.日期.log里找到了错误原因。由此引出问题5

问题5

在日志localhost.日期.log中找到了坑爹的具体出错(SEVERE: Error listenerStart)原因,罪魁祸首就是Log4jConfigListener的配置以及web.xml的问题。

可以参看这里http://blog.csdn.net/lzzyok/article/details/7571727

大体原因是Log4jConfigListener的contextInitialized方法最终会调用WebUtils.setWebAppRootSystemProperty来设置webapp.root,如果root已经存在就会抛出异常。需要修改web.xml。

至此已无力吐槽,以前都是通过log4j.properties来配置log4j,第一次接手别人用xml的配置文件来用的就死里面了,一步就迈进去了啊。因为原来项目配置文件、目录结构太过错乱,我已经花时间重新整理过了,单单漏下了这个该死的log4j.xml配置,擦屁股的事情真是不好做。

问题6

再次启动查看问题5是否已经不存在,如果按问题5里的描述修改web.xml后还不行,果断删掉log4j.xml配置,使用log4j.properties的形式。不得不说下Java的臃肿了,和臃肿的XML真是天生一对难兄难弟啊。

总结

好吧,说到这里,除了问题2,其他的按各问题描述方法修改后,相应错误已经不再出现。但如果仍出现编译问题,就说明你中了大奖了。这里提供几个解决方案:

  • 统一所有环境,开发机、测试机、线上机,如果线上机修改成本不大,建议换用高版本JDK。以此来尽量保证开发、编译、运行环境一致。
  • 如果本地不好更新JDK,比如我的机器装不上JDK6,那么就不要使用本地编译的版本,可以服务器搭建jenkins编译。
  • 还不行的话,把电脑砸了,把服务器删了,然后出门潇洒去吧。。