尝试使用Maven运行JUnit5测试时,出现了java.lang.NoClassDefFoundError: org/junit/platform/commons/PreconditionViolationException错误。

46
尝试使用命令mvn test运行测试时,我收到了一个错误:
[ERROR] There was an error in the forked process
[ERROR] java.lang.NoClassDefFoundError: org/junit/platform/commons/PreconditionViolationException
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] java.lang.NoClassDefFoundError: org/junit/platform/commons/PreconditionViolationException
[ERROR]         at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:656)
[ERROR]         at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:282)
[ERROR]         at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:245)
[ERROR]         at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1183)
[ERROR]         at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1011)
[ERROR]         at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:857)
[ERROR]         at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
[ERROR]         at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
[ERROR]         at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
[ERROR]         at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
[ERROR]         at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
[ERROR]         at org.apache.maven.cli.MavenCli.execute(MavenCli.java:956)
[ERROR]         at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
[ERROR]         at org.apache.maven.cli.MavenCli.main(MavenCli.java:192)
[ERROR]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)

我在IntelliJ 2008.1下运行它,使用maven 3.6.1和2.22.1版本的surefire插件。

我的pom文件中有以下依赖项:

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.5.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.5.0</version>
    <scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.5.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-launcher</artifactId>
    <version>1.5.0</version>
    <scope>test</scope>
</dependency>

...

<plugins>
    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
    </plugin>
</plugins>

最近我无法运行任何测试用例,但现在经过一些配置尝试后,我收到了以下错误。


1
mvn clean 运行测试?我对此表示怀疑...移除 platform-launcher,通常只需要 junit-jupiter-engine 来运行 JUnit 5 测试...如果您有参数化测试,则需要 junit-jupiter-params...此外,我建议使用 Junit Jupiter 团队的 bom,这样更容易处理... - khmarbaise
13个回答

53

2
在我的情况下,我实际上同时拥有junit-jupiterjunit-jupiter-params。这导致了冲突。只需要拥有junit-jupiter即可。 - labm0nkey
3
无法运行,报错信息为java.lang.ClassNotFoundException: org.junit.platform.engine.EngineDiscoveryListener - Kango_V

29

添加以下依赖项在我的情况下有所帮助

 <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-commons</artifactId>
            <version>1.5.2</version>
 </dependency>

junit-platform-commons-1.5.2.pom 只包含 apiguardian-api 构件,我仍然在想这怎么能解决依赖冲突的问题。 - Prasanth Rajendran
这对我也起作用了,但您能否解释一下为什么它解决了这个错误? - Fakipo

22

正如其他人建议的那样,使用JUnit 5.5.2版本是正确的做法。 有不同的替代方案可供选择:

  1. 如果您正在使用spring-boot-starter-parent,可以将其升级到2.2.0.RELEASE
  2. 如果您使用spring-boot-starter-parent(或spring-boot-dependencies),可以定义一个属性来更新JUnit:<junit-jupiter.version>5.5.2</junit-jupiter.version>
  3. 如果您在Eclipse中遇到了这个问题,可以更新它并将JUnit 5库添加到Java Build Path(项目> Java Build Path>库>添加库> JUnit> JUnit 5>完成
  4. 您可以添加Junit BOM,使用5.5.2版本(参见Prasanth Rajendran Ramit 的回答)

1
完美的答案(第三个修复了我的问题) - thonnor

11

我遇到了与Gradle构建相同的问题,使用JUnit材料清单(BOM)解决了我的问题,它将管理JUnit的直接和传递依赖项版本。

dependencyManagement {
    imports {
        mavenBom "org.junit:junit-bom:5.5.2"
    }
}
dependencies {
...
    testCompile('org.junit.jupiter:junit-jupiter-api')
    testRuntime('org.junit.jupiter:junit-jupiter-engine')
    testCompile('org.junit.jupiter:junit-jupiter-params')
    testCompile('org.junit.platform:junit-platform-launcher')
    testCompile('org.junit.platform:junit-platform-runner')
}

注意:我没有指定版本,因为Junit BOM会负责Junit依赖版本管理的角色。


谢谢!我在VScode上尝试了这个,也遇到了相同的“找不到类定义”错误。对我来说,只需添加依赖项就可以解决问题! - Shivansh Jagga

10

使用surefire.plugin.version 2.22.2对我有用

junit-jupiter artifact会引入所有其他必要的artifacts。

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.junit</groupId>
      <artifactId>junit-bom</artifactId>
      <version>5.5.2</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
<dependencies>
  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
  </dependency>
  <!--Optional: Supports running Junit4 along with Junit5 -->
  <dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

3

几天前,我遇到了类似的问题。我尝试了这里提出的所有解决方案,但都没有起作用。在我的情况下,错误是因为classpath中有两个不同版本的JUnit。我有一个使用JUnit 5.3.2的spring-boot-test依赖项。但是,我又添加了JUnit 5.7.1。因此,我的项目是使用较新版本的JUnit (5.7.1)编译的,但在运行时发现了较旧版本(5.3.2)。结果,JUnit启动器尝试使用在较旧版本的JUnit中不可用的类。在我的情况下,解决方案是像这样覆盖Spring管理的JUnit版本:

<properties>
    <junit-jupiter.version>5.7.1</junit-jupiter.version>
</properties>

希望这篇内容对某些人有所帮助。

1
在生产代码中包含某些测试类(来自junit/assertj)时,您可能会遇到“java.lang.NoClassDefFoundError: org/junit/platform/commons/util/Preconditions”这样的错误。
以上是以下情况的结果:
- 将测试库作为不在测试范围内的依赖项(因此使其在运行时可用) - 可能会在生产代码 - src/main/java 中导入此类测试实用程序类(例如,您使用import org.assertj.core.util.Lists从src/main/java导入生产代码中的列表)。 - 还有可能将此类测试库添加为java9模块信息的一部分(例如requires org.assertj.core)。
注意:此冒犯依赖项可能在您的模块内或包含在依赖项中的任何模块中。
例如,您的模块具有以下依赖项:
    <dependency>
        <groupId>com.acme</groupId>
        <artifactId>your-another-module</artifactId>
    </dependency>

你的另一个模块包含了 scope 为 compile 的 spring-boot-starter-test:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>compile</scope> <!-- **or even scope is omitted and by default it is compile !** -->
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

如上面代码片段所示,作用域甚至可能被省略,默认为“编译”。

现在根据该错误,您的模块中可能有一个生产类YourClass,并且意外地从测试库中导入了一些测试代码,例如:

// here we have accidential import of Lists from assertj
import org.assertj.core.util.Lists;
class YourClass {

}

解决方案如下:
  • 修复依赖项,使它们在范围测试中,并在生产代码中使用正确的导入
  • 清理 module-info.java,删除任何不需要在生产代码中使用的测试库

1
在我的情况下,问题在删除本地Maven存储库后消失了。不知道是哪个库导致了这种奇怪的行为,但现在一切都正常工作了!

1

尝试将 Junit 升级到 5.8.2 或更高版本,请参见此处可用的 Jupter Junit 版本

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.8.2</version>
    <scope>test</scope>
</dependency>

junit-platform-commons 是 Junit 的可交互依赖项,因此如果您升级 Junit,则这些可交互依赖项也将被更新。


0

当尝试使用maven运行junit5测试时,可能会出现java.lang.NoClassDefFoundError: org/junit/platform/commons/PreconditionViolationException错误。

这个错误可能是由于junit-plateform-engine、junit-jupiter-params和junit-platform-runner以及其他相应的依赖项版本不匹配造成的。

因此,为了解决这个问题,您不需要像1.5.3等那样定义版本。

您可以按如下方式定义版本:

<dependencies>
<!--need to add for parameterized test -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-params</artifactId>
        **<version>${junit.jupiter.version}</version>**
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        **<version>${junit.jupiter.version}</version>**
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-runner</artifactId>
        **<version>${junit.platform.version}</version>**
        <scope>test</scope>
    </dependency>
</dependencies>

因此,通过这个兼容版本的jar包将被添加到您的项目中,并且项目将成功运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接