【问题标题】:How to prevent duplicate servlet jar using eclipse+m2eclipse如何使用eclipse+m2eclipse防止重复的servlet jar
【发布时间】:2011-08-19 19:41:01
【问题描述】:

我正在使用 Eclipse + Maven + m2eclipse 在 Apache Tomcat 中构建和测试一个 Web 应用程序。

我已经在 Eclipse 中配置了一个 Tomcat 服务器,并为我的 Web 应用程序配置了部署程序集,包括“Maven 依赖项”(Java 构建路径条目的专门化)。

当我部署和启动服务器时,Tomcat/Catalina 总是警告我:

信息:validateJarFile(/projects/src/main/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/webapp/WEB-INF/lib/servlet-api-2.5. jar) - jar 未加载。请参阅 Servlet 规范 2.3,第 9.7.2 节。违规类:javax/servlet/Servlet.class

这是因为 m2eclipse 将 servlet-api-2.5 视为我项目的依赖项,并将其视为“Maven 依赖项”的一部分,并将其作为部署程序集的一部分进行复制,但 Tomcat servlet 容器有自己的副本并且不喜欢在类路径上看到 2 个副本。

我已经在我的 pom.xml 中标记了从我的项目到 servlet-api-2.5 的依赖关系

<scope>
provided
</scope>

这确实阻止了独立的 Maven 将 servlet-api-2.5 打包到我的构建中,但 m2eclipse 不这么认为。

(这没什么大不了的,因为警告是无害的,我只在 IDE 内部测试时看到它,真正的客户不会看到它,但我仍然想知道如何修复它,因为我喜欢清洁,我喜欢了解事物的运作方式。)

有没有正确的方法告诉m2eclipse不要部署这个文件,或者告诉Eclipse不要让m2eclipse对哪些依赖是运行时依赖有最终决定权?

我确实找到了提到的https://issues.sonatype.org/browse/MNGECLIPSE-1193

“Maven Dependencies”容器反映了测试编译时范围,因此它应该具有范围为“provided”的依赖项

【问题讨论】:

  • 你能展示一下这个项目的 pOM 吗?您是否测试过将范围标签放在一行中?您是否有其他依赖项自己的项目或传递项目?你检查过依赖树吗?
  • @khmarbaise 我已经使用“mvn dependency:tree”检查了依赖树,并且对 servlet-api 的每个引用都提供了范围。 (例如:javax.servlet:servlet-api:jar:2.5:provided(从 2.3 管理的版本;从编译管理的范围))。实际上,我确实在一行中有范围标签,尽管我真的希望没有 xml 解析器会关心这一点。
  • 你是如何打包你的战争的?
  • 没有战争,只是一堆罐子。这一堆 jar 在 Eclipse 的临时部署目录(.project/metadata/tmp/.../wtpwebapp)中包含 servlet-api-2.5.jar,但在我使用“mvn package”构建时不在我的真实目标目录中。跨度>
  • 可能是我的问题不够清楚。您是否 maven build 创建了一个包含正确文件的 war 文件以及如何通过 maven-war-plugin 打包(打包设置为 war?)?

标签: maven m2eclipse


【解决方案1】:

从更新站点 http://m2eclipse.sonatype.org/sites/m2e-extras 安装 m2eclipse 插件的附加功能(“Maven 集成为 WTP”)。安装后,更新项目配置。

【讨论】:

【解决方案2】:

通常在您的项目中存在依赖于 servlet-apî.jar 的依赖项

Maven 的默认行为是我会尝试导入您的依赖项 + 导入的依赖项的依赖项。

如果你想排除特定的“子依赖”,你可以给maven这样的配置:

<dependency>
    <groupId>com.hpsworldwide.mbtrs.switch</groupId>
    <artifactId>YOUR_DEPENDENCY</artifactId>
    <version>1.0</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

然后 maven 将导入 YOUR_DEPENDENCY + 所有 YOUR_DEPENDENCY 依赖项,但会将 servlet-api 从 YOUR_DEPENDENCY 的依赖项中排除。

【讨论】:

  • 幸运的是我明白了这一点,我猜,答案可以解释我们如何知道 pom 依赖项以在正确的依赖项中排除 servlet-api
【解决方案3】:

我刚刚遇到了类似的问题,相信我已经找到了问题的根源。

如果您在 Eclipse 中转到您的服务器配置设置并选择“服务模块而不发布”,那么这应该不再发生。

Maven/M2Eclipse 正在正确构建 WAR - servlet-api-2.5.jar 不会在您的目标目录或 WAR 文件中。

但问题是,当您通过 Eclipse 将应用程序部署到您的 tomcat 时,Eclipse 不会默认使用您的 Maven 构建的 WAR/target 目录,它只是为您的项目使用正常的 Eclipse“导出”设置。因此,它会在您的“Java EE 模块”(或“部署程序集列表”,如果您使用 Helios)中看到 Maven_Dependencies 中所有 jar 的列表,但它不尊重范围,只是部署所有 jar。

如果您选择服务而不发布选项,那么 Eclipst/Tomcat 应该直接从您的目标目录运行应用程序,这样会尊重 maven 范围。

它永远不会影响您的实时部署(除非您通过 eclipse 进行部署!),因为 maven 正在做正确的事情,但它有时会在本地导致问题,因为您可能会遇到冲突的 servlet/jsp jar,这可能会导致 classcastexceptions 和普遍的苦难......

【讨论】:

  • 谢谢,这听起来很合理。它似乎对我不起作用,因为当我选择“服务模块而不发布”并启动服务器时,它无法以 jira.codehaus.org/browse/MTOMCAT-6 和 jira.codehaus.org/browse/MTOMCAT-49 之类的调用堆栈启动(但 #6 很久以前就已修复并且#49 未能指定我正在做的范围=提供)。我不认为我实际上在使用 mtomcat 所以这可能不是同一个原因,但它并不快乐。
  • 您使用的是 Eclipse Helios 还是旧版本?
  • 您能否提供当您尝试在不发布的情况下提供模块时获得的堆栈跟踪?看起来你可能会遇到我试图让 Helios 很好地使用 maven 设置并在不发布的情况下提供模块时遇到的完全相同的问题 (stackoverflow.com/questions/5924720/…)
  • 这里:pastebin.com/NcqncHe3。对于无法转换为 javax.servlet.Filter 的其他几个类,同样的事情也会重复。 (注意,o.sf.w.f.DelegatingFilterProxy 确实实现了 javax.servlet.Filter,所以强制转换应该是合法的——static.springsource.org/spring/docs/1.2.9/api/org/…)
  • 是的,这看起来与我尝试在不发布的情况下提供服务时得到的堆栈跟踪相似。不幸的是,我仍在努力追根究底(与此同时,如果不发布并手动删除本地服务器中的 jar,则不提供服务),但如果我发现任何其他内容,我会更新
【解决方案4】:

如果您使用 Indigo,您可以通过单击“Window”->“Preferences”->“Maven”->“Discovery”->“Open Catalog”找到 WTP 插件。

【讨论】:

    【解决方案5】:

    提示:安装“Maven Integration for WTP”并更新项目配置后,检查目录 /WEB-INF/lib 并删除其中的所有 JAR。现在,清理 Tomcat 工作目录并再次运行。

    【讨论】:

      猜你喜欢
      • 2012-06-15
      • 2012-02-08
      • 2012-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      • 2018-05-18
      • 1970-01-01
      相关资源
      最近更新 更多