【问题标题】:Maven compile fails silently - Unresolved compilation problemsMaven 编译失败 - 未解决的编译问题
【发布时间】:2017-12-02 00:02:27
【问题描述】:

我有一个关于 spring webapp maven 构建的有趣问题。当在 eclipse 中构建时一切都很好,但是当通过 maven 构建并部署到 tomcat 8 容器时,webapp 在启动时失败并出现以下错误:

Caused by: java.lang.NoClassDefFoundError: FilterConfig

现在我尝试了所有明显且有据可查的依赖问题(设置 javax.servlet-api 和 jsp-api 导入提供的范围并确保它们是最新版本,因为这是一个 Java 8 项目)。我已确保所有编译器插件都是最新版本:

maven 战争插件 3.1.0

maven 编译器插件 3.6.1

然而,webapp 无法启动,maven 构建控制台输出中没有显示任何错误。在(工作的)eclipse构建和神秘失败的maven等价物之间进行了许多令人头疼和艰苦的比较之后,发现在maven生成的一些类文件中是描述编译问题的文本。 (以下内容是从 Eclipse 中针对 .class 文件的“打开方式 > 文本编辑器”选项中提取的 - 某些字符必须省略,因为它们无法正确复制)

Unresolved compilation problems: 
    The import javax.servlet.Filter cannot be resolved
    The import javax.servlet.FilterChain cannot be resolved
    The import javax.servlet.FilterConfig cannot be resolved
    The import javax.servlet.ServletException cannot be resolved
    The import javax.servlet.ServletRequest cannot be resolved
    The import javax.servlet.ServletResponse cannot be resolved
    The import javax.servlet.http.HttpServletRequest cannot be resolved
    The import javax.servlet.http.HttpSession cannot be resolved
    Filter cannot be resolved to a type
    FilterConfig cannot be resolved to a type
    ServletException cannot be resolved to a type
    ServletRequest cannot be resolved to a type
    ServletResponse cannot be resolved to a type
    FilterChain cannot be resolved to a type
    ServletException cannot be resolved to a type
    HttpServletRequest cannot be resolved to a type
    HttpServletRequest cannot be resolved to a type
    HttpSession cannot be resolved to a type

我无法理解 maven 进程是如何成功完成的,并且我尝试过的任何 mvn 目标都没有显示错误

mvn 编译器:编译

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building xxxx 2.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ EBPP ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 5 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.6.1:compile (default-compile) @ EBPP ---
[INFO] Nothing to compile - all classes are up to date
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.413 s
[INFO] Finished at: 2017-06-28T15:11:45+01:00
[INFO] Final Memory: 9M/213M
[INFO] ------------------------------------------------------------------------

上面,但带有 -x 显示了很多调试输出,但没有提示编译问题,实际上它表明包含了类文件标识的未解决的依赖项

...
[DEBUG]    javax.servlet:javax.servlet-api:jar:3.1.0:provided  
[DEBUG]    org.apache.velocity:velocity:jar:1.7:compile
[DEBUG]    commons-collections:commons-collections:jar:3.2.1:compile 
[DEBUG]    commons-lang:commons-lang:jar:2.4:compile 
[DEBUG]    javax.servlet.jsp:jsp-api:jar:2.2:provided 
...

mvn 依赖:构建类路径

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building xxxx 2.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:build-classpath (default-cli) @ EBPP ---
[INFO] Dependencies classpath:
C:\Users\xxxxxx\.m2\repository\org\springframework\webflow\spring-webflow\2.4.5.RELEASE\spring-webflow-2.4.5.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\xxxxxx\.m2\repository\opensymphony\ognl\2.6.11\ognl-2.6.11.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\webflow\spring-binding\2.4.5.RELEASE\spring-binding-2.4.5.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\webflow\spring-js\2.4.5.RELEASE\spring-js-2.4.5.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\webflow\spring-js-resources\2.4.5.RELEASE\spring-js-resources-2.4.5.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\spring-beans\4.3.0.RELEASE\spring-beans-4.3.0.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\spring-context\4.3.0.RELEASE\spring-context-4.3.0.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\spring-aop\4.3.0.RELEASE\spring-aop-4.3.0.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\spring-expression\4.3.0.RELEASE\spring-expression-4.3.0.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\spring-web\4.3.0.RELEASE\spring-web-4.3.0.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\spring-webmvc\4.3.0.RELEASE\spring-webmvc-4.3.0.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\spring-core\4.3.9.RELEASE\spring-core-4.3.9.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\com\xxxxxxx\ebpp\JComms\2.0.1\JComms-2.0.1.jar;C:\Users\xxxxxx\.m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\Users\xxxxxx\.m2\repository\javax\mail\mail\1.4.7\mail-1.4.7.jar;C:\Users\xxxxxx\.m2\repository\javax\activation\activation\1.1\activation-1.1.jar;C:\Users\xxxxxx\.m2\repository\org\apache\httpcomponents\httpclient\4.5.1\httpclient-4.5.1.jar;C:\Users\xxxxxx\.m2\repository\org\apache\httpcomponents\httpcore\4.4.3\httpcore-4.4.3.jar;C:\Users\xxxxxx\.m2\repository\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;C:\Users\xxxxxx\.m2\repository\commons-httpclient\commons-httpclient\3.1\commons-httpclient-3.1.jar;C:\Users\xxxxxx\.m2\repository\com\xxxxxxx\ebpp\JCore\2.0.1\JCore-2.0.1.jar;C:\Users\xxxxxx\.m2\repository\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar;C:\Users\xxxxxx\.m2\repository\org\apache\velocity\velocity\1.7\velocity-1.7.jar;C:\Users\xxxxxx\.m2\repository\commons-collections\commons-collections\3.2.1\commons-collections-3.2.1.jar;C:\Users\xxxxxx\.m2\repository\commons-lang\commons-lang\2.4\commons-lang-2.4.jar;C:\Users\xxxxxx\.m2\repository\javax\servlet\jsp\jsp-api\2.2\jsp-api-2.2.jar;C:\Users\xxxxxx\.m2\repository\junit\junit\3.8.2\junit-3.8.2.jar;C:\Users\xxxxxx\.m2\repository\org\springframework\spring-context-support\4.3.9.RELEASE\spring-context-support-4.3.9.RELEASE.jar;C:\Users\xxxxxx\.m2\repository\com\xxxxxxx\xxxxxxx\440\xxxxxxx-440.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.331 s
[INFO] Finished at: 2017-06-28T15:13:05+01:00
[INFO] Final Memory: 13M/213M
[INFO] ------------------------------------------------------------------------

mvn 验证

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building xxx 2.0.1
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.109 s
[INFO] Finished at: 2017-06-28T15:15:32+01:00
[INFO] Final Memory: 7M/213M
[INFO] ------------------------------------------------------------------------

我真的很难过。我假设 maven 正在使用与 eclipse 不同的编译器,但我真的没有想法了。

有没有其他人遇到过这种情况?

提前致谢。

【问题讨论】:

  • 一个很长的镜头,但也许:您是否在 Eclipse 中检查了“自动构建”,但通过命令行运行? Eclipse 自己构建,并且可能会尝试这样做,在同一个文件夹中,与 maven 同时,事情可能会发生冲突。
  • 嗯,我通常在 Eclipse “运行为 > Maven clean”中构建 maven,然后“运行为 >Maven 安装”。只是为了确保我尝试自动关闭构建,但它仍然是一个问题。 :-/

标签: java eclipse maven


【解决方案1】:

我怀疑它是 Eclipse 构建文件和编译错误的组合(是的,Eclipse 可以做到这一点:如果你永远不会到达不可编译的代码,那么你甚至不会得到错误)和 Maven 没有清理输出首先是 Eclipse。

然后 Maven 看到该文件是最新的,并且不会覆盖它。

我建议以下(检查我是否正确):

  • 关闭 Eclipse 的自动构建(或完全停止 Eclipse)。
  • 运行一个 Maven 目标,例如package,但也运行clean(即mvn clean package);关键是要 100% 确定 Maven 构建这些文件而不是 Eclipse。
  • Maven 现在应该报告编译错误。

至于错误本身,看起来您确实缺少依赖项(但可能在 Eclipse 的类路径中,而不是 Maven 的)。

【讨论】:

  • 所以我尝试自动关闭 Eclipse 的构建,然后在执行项目清理后完全关闭 Eclipse(未选中启动构建)。然后我在项目目录中运行 mvn package(此时没有目标目录)。 mvn 命令成功完成,没有错误,并创建了一个目标目录。然后我重新打开 eclipse 来查看生成的类文件的内容(因为我的文本编辑器没有显示相同的视图)......唉,它是一样的。
  • 顺便说一句,在我的 Eclipse 构建路径中,我只使用 Maven 依赖项,一旦在项目属性窗口中展开,就会显示 javax.servlet-api-3.1.0.jar 存在。 ...我认为 maven 必须将这些未解决的编译问题留在那里,希望代码不会被访问?该代码实际上是 web.xml 中指定的过滤器,因此在启动时会出现。
  • 有趣的是,我刚刚注意到在目标目录中有一个类目录,其中包含(看起来是)正确编译的类。这是项目的 .war 文件和编译文件夹(包含错误构建的类)的补充。
  • Eclipse 类路径和 Maven 可能略有不同。为什么这个 jar 显示为 provided?不应该是compile吗? javax.servlet:javax.servlet-api:jar:3.1.0:提供
  • 感谢您的努力,安德烈。我找到了原因(在下面回答)
【解决方案2】:

因此,当将此项目与另一个成功的项目(均从 Java 4 转换而来)进行比较时,预感使用非标准目录名称是 maven 行为不稳定的原因(在复制 warSourceDirectory 时)。我分析了(现在称为)WebRoot > WEB-INF > classes 目录,发现对于有问题的应用程序,它已经被填充,你已经猜到了 - 错误编译的类文件!显然,war 插件将这些坏文件复制到 Maven 拥有的文件的顶部,在同一个构建过程中刚刚成功编译 - 因此没有错误。

我不确定为什么有坏文件,因为它们不在旧的 Java 4 项目中。我怀疑它们一定是在先前失败的 Maven 构建期间使用不正确的设置以某种方式创建的。

【讨论】:

    猜你喜欢
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多