Java NoSuchMethodError: org.junit.platform.commons.util.ReflectionUtils.tryToLoadClass

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53926264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:56:13  来源:igfitidea点击:

NoSuchMethodError: org.junit.platform.commons.util.ReflectionUtils.tryToLoadClass

javaintellij-ideadependenciesjunit5junit-jupiter

提问by Bizon4ik

I have the test that leads to error. I tried to execute it in the IntelliJ Idea 2018.3.2. All jupiter and junit dependencies have version RELEASE

我有导致错误的测试。我试图在 IntelliJ Idea 中执行它2018.3.2。所有 jupiter 和 junit 依赖项都有版本RELEASE

The full text of error:

错误全文:

Dec 26, 2018 1:17:17 AM org.junit.platform.launcher.core.DefaultLauncher handleThrowable
WARNING: TestEngine with ID 'junit-jupiter' failed to execute tests
java.lang.NoSuchMethodError: org.junit.platform.commons.util.ReflectionUtils.tryToLoadClass(Ljava/lang/String;)Lorg/junit/platform/commons/function/Try;
at org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector.createAbortedExecutionPredicate(OpenTest4JAndJUnit4AwareThrowableCollector.java:40)
at org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector.<clinit>(OpenTest4JAndJUnit4AwareThrowableCollector.java:30)
at org.junit.jupiter.engine.support.JupiterThrowableCollectorFactory.createThrowableCollector(JupiterThrowableCollectorFactory.java:34)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:68)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute(DefaultLauncher.java:188)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

the test has the following view

测试有以下观点

import biz.Services.msg.BookTimeMsgService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.assertTrue;

@ExtendWith(MockitoExtension.class)
public class MsgReceiverTest {

@Mock
BookTimeMsgService bookTimeMsgService;

@InjectMocks
MsgReceiver msgReceiver;

@Test
public void msgReceiverTest_bookTimeServiceShouldObtainMsg() {
    assertTrue(true);
}

part of my pom.xml

我的 pom.xml 的一部分

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
</parent>

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>RELEASE</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>RELEASE</version>
        <type>pom</type>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-junit-jupiter</artifactId>
        <version>RELEASE</version>
        <scope>test</scope>
    </dependency>

How to fix the issue?

如何解决问题?

采纳答案by Bizon4ik

I changed the version of jupiter and junit to 5.3.2 and the problem has gone

我将jupiter和junit的版本改为5.3.2,问题就解决了

回答by Terran

I was able to run the Junit 5 tests after adding the platform and launcher dependency:

添加平台和启动器依赖项后,我能够运行 Junit 5 测试:

<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-commons -->
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-commons</artifactId>
    <version>1.4.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher -->
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-launcher</artifactId>
    <version>1.4.0</version>
    <scope>test</scope>
</dependency>

回答by Maksim Kostromin

minimal required pom.xml setup for spring-boot 2.1.3 and junit 5.4.0 testing next:

下面是 spring-boot 2.1.3 和 junit 5.4.0 测试所需的最少 pom.xml 设置:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  <parent>
    <groupId>org.springframework.boot</g..roupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.3.RELEASE</version>
    <relativePath/>
  </parent>

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

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

回答by Jacek K.

use:

用:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.4.2</version>
    <scope>test</scope>
</dependency>

instead

反而

<dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
</dependency>
<dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <scope>test</scope>
</dependency>

you can find more details here

你可以在这里找到更多细节

回答by user2051552

Combos of Maven/Gradle, Eclipse/IntelliJ using Spring Boot/or not while including Junit4/Junit5 throw different flavors of this NoSuchMethodError. This leads to many different solutions all of which only fix a portion of people's problems. This long winded answer is an attempt to explain the root cause and steps you can take to fix your problem whichever flavor you are using.

Maven/Gradle、Eclipse/IntelliJ 的组合使用 Spring Boot/或不包括 Junit4/Junit5 时抛出此 NoSuchMethodError 的不同风格。这导致了许多不同的解决方案,所有这些解决方案都只能解决一部分人的问题。这个冗长的答案试图解释根本原因以及您可以采取的解决问题的步骤,无论您使用哪种口味。

Root cause:
At compile time, one version of ReflectionUtils (I've seen other classes here too) was used, and at runtime, a different one was used. The runtime version was expecting a certain method to exist, but either it didn't exist, or it existed with a different signature (number/type of parameters)

根本原因:
在编译时,使用了一个版本的 ReflectionUtils(我在这里也看到了其他类),而在运行时,使用了另一个版本。运行时版本期望某个方法存在,但它要么不存在,要么具有不同的签名(参数的数量/类型)

Note, when I say compile time, this can mean (and usually does) mean the version of ReflectionUtils that was used to compile a third party jar inside your classpath.

请注意,当我说编译时间时,这可能意味着(并且通常确实)意味着用于在类路径中编译第三方 jar 的 ReflectionUtils 版本。

The solution will always be to change or exclude some version of some jar. The trick is to find which jar and which version.

解决方案将始终是更改或排除某些 jar 的某个版本。诀窍是找到哪个 jar 和哪个版本。

To solve:
First, identify what version of ReflectionUtils (or other class it is complaining about) is being used at runtime. This is fairly easy. In eclipse, do an Open Type, in IntelliJ, use a navigate/go to class. Make sure to fully qualify the path. If you have exactly 1 version on the path, this is good. If you have more than on version on the path, your first action to take is to modify your build path to exclude one of the versions.

解决方法:
首先,确定运行时使用的是哪个版本的 ReflectionUtils(或它抱怨的其他类)。这相当容易。在 eclipse 中,做一个 Open Type,在 IntelliJ 中,使用导航/转到类。确保完全限定路径。如果路径上正好有 1 个版本,这很好。如果路径上有多个版本,则您要采取的第一个操作是修改构建路径以排除其中一个版本。

If you cannot modify the build path, even temporarily, it is harder to identify what version of ReflectionUtils is being used at runtime. Since JUnit 4 and 5 begins and dies before you can run any of your code, you cannot insert a

如果您不能修改构建路径,即使是暂时的,也很难确定运行时使用的是哪个版本的 ReflectionUtils。由于 JUnit 4 和 5 在您可以运行任何代码之前开始并结束,因此您不能插入

CodeSource src = ReflectionUtils.class.getProtectionDomain().getCodeSource();
if (src != null) {
    URL jar = src.getLocation();
    System.out.println(jar.toString());
}

to get the location of the runtime jar. But you can try:

获取运行时 jar 的位置。但是你可以试试:

1 - create a fresh new project, a fresh pom, put 1 junit inside of it, and run it with the above code and see what comes out. This may work because whatever conflict was in the non working project has been removed. This may not work in which case move to #2. This also may give a false result because the runtime path of a fresh project may be different than that of the non working project. Try updating the pom of the fresh project to look more and more like that of the non working project. Remember, the goal is to find what version of the class is being used at runtime

1 - 创建一个全新的项目,一个全新的 pom,将 1 个 junit 放入其中,然后使用上面的代码运行它,看看会发生什么。这可能有效,因为非工作项目中的任何冲突都已被删除。在这种情况下,这可能不起作用,请移至 #2。这也可能会给出错误的结果,因为新项目的运行时路径可能与非工作项目的运行时路径不同。尝试更新新项目的 pom,使其看起来越来越像非工作项目的 pom。请记住,目标是找到运行时正在使用的类的版本

2 - Use google. Yah I know you got here by using google but this time change your search to see if someone documented "This version of JUnit5 uses this version of ReflectionUtils at runtime" or "This version of IntelliJ puts this version of ReflectionUtils on the classpath" or "This version of Spring Boot is putting this version of ReflectionUtils on the classpath". Remember, the goal is to find what version of the class is being used at runtime

2 - 使用谷歌。是的,我知道您是通过使用 google 来到这里的,但是这次更改您的搜索以查看是否有人记录了“此版本的 JUnit5 在运行时使用此版本的 ReflectionUtils”或“此版本的 IntelliJ 将此版本的 ReflectionUtils 放在类路径上”或“此版本的 Spring Boot 将此版本的 ReflectionUtils 放在类路径上”。请记住,目标是找到运行时正在使用的类的版本

3 - HiHyman a class (advanced). When the stacktrace comes out, you will see several classes in the stacktrace. Try to find the source code for the class on the internet and create that package and class in your project. Then insert the code above and try to run the test which was failing.

3 - 劫持一个班级(高级)。当stacktrace出来时,你会在stacktrace中看到几个类。尝试在 Internet 上查找该类的源代码并在您的项目中创建该包和类。然后插入上面的代码并尝试运行失败的测试。

Once you have found which version of ReflectionUtils is used at runtime, you need to find out what version was used at compile time

一旦找到运行时使用的 ReflectionUtils 版本,就需要找出编译时使用的版本

Identify which jar ReflectionUtils lives inside.

确定哪个 jar ReflectionUtils 位于里面。

In the stacktrace which pops out when you run your test, identify the top class and method which died trying to use ReflectionUtils. This is the code which was compiled with an incompatible version of ReflectionUtils. Find out what jar that class is inside. I'll call this jar the conflicting jar. Try and get a dependency tree for that conflicting jar. The dependency tree should indicate which version of the ReflectionUtils jar the conflicting jar was dependent on.

在运行测试时弹出的堆栈跟踪中,确定尝试使用 ReflectionUtils 时失败的顶级类和方法。这是使用不兼容版本的 ReflectionUtils 编译的代码。找出那个类在什么罐子里。我会称这个 jar 为冲突的 jar。尝试为那个冲突的 jar 获取一个依赖树。依赖关系树应该表明冲突的 jar 依赖于哪个版本的 ReflectionUtils jar。

Once you have found which version of ReflectionUtils jar was used at compile time and runtime, you likely will see that they are different and also incompatible. At this point, you will have to

一旦您发现在编译时和运行时使用了哪个版本的 ReflectionUtils jar,您可能会发现它们不同且不兼容。此时,您将不得不

1 - change the version of the ReflectionUtils jar used at runtime to match the version of ReflectionUtils needed by the conflicting jar

1 - 更改运行时使用的 ReflectionUtils jar 版本以匹配冲突 jar 所需的 ReflectionUtils 版本

2 - change the version of the conflicting jar to one which is dependent on the same version of the ReflectionUtils jar which is on the runtime path

2 - 将冲突 jar 的版本更改为依赖于运行时路径上相同版本的 ReflectionUtils jar

3 - if the conflicting jar is a dependency of some parent jar in build path and not explicity included by your build path, try excluding the conflicting jar from the parent jar and add a newer version explicitly. This may solve the problem - but this is, of course, the type of behavior which created this mess in the first place.

3 - 如果冲突 jar 是构建路径中某个父 jar 的依赖项,并且未明确包含在您的构建路径中,请尝试从父 jar 中排除冲突 jar 并显式添加更新版本。这可能会解决问题——但这当然是首先造成这种混乱的行为类型。

Other actions you can take:
If you know that you are using both JUnit4 jars as well as JUnit5 in your project, try removing one or the other completely from the compile time and runtime paths. The Assert patterns of the two paradigms are different enough that you likely do not want to mix them in the same project as it could lead to confusion of which parameters are the expected results, the message, and the variable under test.

您可以采取的其他操作:
如果您知道在项目中同时使用 JUnit4 jar 和 JUnit5,请尝试从编译时和运行时路径中完全删除其中一个。两种范式的断言模式差异很大,您可能不希望将它们混合在同一个项目中,因为这可能会导致混淆哪些参数是预期结果、消息和被测变量。