500报错,记一次奇怪的集成经历

昨天我在公司给项目集成 Spring MVC 时,发生了一件匪夷所思的事情:我单独创建的 Spring MVC 工程运行正常,但我将相关文件移植到现项目中,启动项目,用浏览器访问任意页面时,就报错了。我检查了好几遍都没发现问题,debug 也看不出个所以然。

部分报错新信息如下:

======================

HTTP Status 500 - java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;

type Exception report

message java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem; org.apache.jasper.servlet.JspServlet.service(JspServlet.java:273) javax.servlet.http.HttpServlet.service(HttpServlet.java:727) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168) org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228) org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) javax.servlet.http.HttpServlet.service(HttpServlet.java:620) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) javax.servlet.http.HttpServlet.service(HttpServlet.java:727) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

======================

二屄解决办法

这个报错信息比较让人疑惑,一行和本地相关的代码都没有,而且看起来和 eclipse 相关,可是,我根本没使用 eclipse,用的是 IntelliJ IDEA。但留意首先出错的位置和 jasper 比较相关。经过 Google,发现有好几个都说是 jasper 引起的问题,要删掉 jasper 相关的依赖包。可是,我的项目中并没有用到 jasper!

我用 Ctrl+Shift+N 搜了下 jasper,才发现在项目的 .idea/libraries 目录中,有两个 jasper 相关的配置文件赫然在列!

/home/cao/projects/{my project}/.idea/libraries

Maven__tomcat_jasper_compiler_5_5_23.xml

Maven__tomcat_jasper_runtime_5_5_23.xml

将它们删掉,再运行就好了。但是,这并非正常的解决办法,下次编译,又会出现……

普通解决办法

这个问题,是因为在项目依赖中包含 tomcat_jasper_compiler_5_5_23 和 tomcat_jasper_runtime_5_5_23,则打包时,会将它们的 jar 包打到项目的 WEB-INF/lib 下,但 tomcat 已经有了这两个包,这样就报错了。

通过 mvn dependency:tree 查看,有如下内容:

[INFO] +- org.apache.hadoop:hadoop-common:jar:2.6.0:compile
[INFO] |  +- tomcat:jasper-compiler:jar:5.5.23:runtime
[INFO] |  +- tomcat:jasper-runtime:jar:5.5.23:compile

hadoop common 中依赖了这两个包,在 haoop common 添加相应排除语句:

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.6.0</version>
    <exclusions>
        <exclusion>
            <groupId>tomcat</groupId>
            <artifactId>jasper-compiler</artifactId>
        </exclusion>
        <exclusion>
            <groupId>tomcat</groupId>
            <artifactId>jasper-runtime</artifactId>
        </exclusion>
    </exclusions>
</dependency>

问题部分解决,编译后,再也没有 jasper-compiler 的东西了,但 jasper-runtime 却还是有的,只是看起来不影响 webapp 的运行了。

文艺的结论

简单才美,没事别搞了那么多依赖。