0

在使用 Maven 运行测试时,我遇到了由 ClassNotFoundException 引起的 NoClassDefFoundError。找不到的类肯定存在于我的本地存储库中。

有问题的依赖项如下所示:默认作用域依赖项依赖于一个 jar,该 jar 的作用域标记为已提供,并且类加载器未找到的文件位于该 jar 内。它编译正常,在运行应用程序时找不到文件。

我已经通过将“提供的 jar”明确添加到我的 pom 作为运行时范围的依赖项来修复错误,但我想了解发生了什么。

1)如果我正在运行一些测试,依赖范围=提供的含义是什么?我知道一个servlet容器可以有一些提供的jar,比如servlet-api.jar,但是测试呢?这看起来像是我们的 pom 中的一个错误,不是吗?当我们应该使用“提供”范围时,除了 servlet-api.jar(和类似的 web-server jars)还有其他情况吗?

2)我在寻找这个问题的解决方案时尝试使用maven命令行参数-U。据我了解,它强制 Maven 检查远程存储库并在必要时从那里获取最新的依赖项。一个问题是:如果我没有指定这个命令会发生什么?它总是会从本地存储库中获取过时的依赖项?如果不是,那为什么我需要这个命令?

3) 为了解决这样的问题,最好在编译代码时知道哪些 jars 真正在类路径上,以及在运行代码时哪些是存在的。Maven可以吗?

4

2 回答 2

2

1) 提供总是意味着不应该将依赖项复制到构建的工件中。声明为提供的某些依赖项的测试将不会运行,因为在运行时需要这些依赖项。例如,您可以通过创建自己的配置文件“测试”来解决此问题。因此,在您的“测试”配置文件中,您将依赖项声明为默认范围,这将覆盖提供的范围。之后,您可以使用以下命令运行测试:

`mvn <goal> -PTest`

有关信息,请参阅配置文件简介

2)据我所知,命令行参数 -U 将导致重新获取依赖项,因为您的存储库可能已损坏(例如,如果您更改或删除了其中的文件)。

3)mvn dependency:tree

于 2012-09-18T08:19:32.720 回答
1

1)您可以使用“测试容器”(Jetty,Tomcat)运行测试,在这种情况下,只要范围是有意义的(例如,我在 prod 中使用 tomcat,但使用 jetty 进行单元测试,他们甚至没有具有相同版本的所提供的 jar)。

2) 默认情况下,Maven 采用它在本地 repo 中找到的 jar,如果不是快照,则不会搜索更新的 jar。如果您提供自己的 jar,则应始终增加版本,即使有时很烦人。

3) mvn dependency:tree 可以为您提供项目的所有依赖树。一些 IDE(我使用 eclipse)也为您提供了一些不错的 UI 工具来查看它们。

于 2012-09-18T08:21:07.223 回答