Springboot 报错:NoSuchMethodError: junit.platform.commons.util.ReflectionUtils.getDefaultClassLoader

本文详细记录了在SpringBoot 2.2.x环境下,使用Intellij进行单元测试时遇到的NoSuchMethodError报错问题。经过对JUnit5官方文档的研究和对pom.xml配置的不断调整,最终找到问题根源在于SpringBoot的JUnit依赖冲突。通过调整相关依赖,成功解决了测试报错的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 报错发生环境

  • Intellij 2017.1.3(2017.3 之后可以正常运行)
  • Springboot 2.2.x

2 报错场景

  • 通过 intellij 新建一个最简单项目
  • 创建一个类写一个测试方法
  • 运行测试方法即报错

3 报错原因分析

3.1 报错日志
  • [pom 配置](#4.1 最初阶段)

  • 报的是 NoSuchMethodError 错误,可知类是找到了,但是没有方法,所以肯定是 Jar 版本不对

  • 知道版本不对但是没什么作用,这里用的是 intellij 相关的

Exception in thread "main" java.lang.NoSuchMethodError: org.junit.platform.commons.util.ReflectionUtils.getDefaultClassLoader()Ljava/lang/ClassLoader;
	at org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry.loadTestEngines(ServiceLoaderTestEngineRegistry.java:30)
	at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:53)
	at com.intellij.junit5.JUnit5IdeaTestRunner.createListeners(JUnit5IdeaTestRunner.java:39)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:49)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
3.2 报错问题追踪(3.1) —— 第1次伪解决
  • 问题地址

  • 问题总结

    • junit-jupiter-api 是为 JUnit 5 设计的
    • 而项目又依赖的 JUnit 4
    • 且,测试时使用的 @Test 是 JUnit 5 的注解
  • 查看 pom 配置,发现 test 依赖移除了 junit-vintage-engine,Springboot2.2.x 官方文档中说明,此依赖是适配 junit 4的,如果已经迁移到 junit 5,可移除此依赖(默认是移除的)

  • 修改: 将移除的依赖由 junit-vintage-engine 改为 junit-jupiter-api。并重新注入 Junit 4 的 @Test,即可成功

  • 虽然可以成功运行测试,但是这并不是我们正真的目的,继续往下走!

  • [pom 配置](#4.2 使用 Junit 4 成功用例)

3.3 JUnit 5 官方文档
  • 文档地址

  • 官方文档(4.1.1章)指出:2017.3 之前的 Intellij 绑定了特定的 JUnit 版本

  • 将官方文档说明的依赖添加到项目中,发现还是报错,报错不一样了

  • [pom 配置](#4.3 参照 JUnit 5 官方文档)

java.lang.NoSuchMethodError: org.junit.platform.launcher.Launcher.execute
3.4 报错问题追踪(3.3) —— 第2次伪解决
  • 问题地址

  • 关键: pom.xml 中依赖的 Junit 相关的版本,需要和 IDEA_INSTALLATION_HOME/plugins/junit/lib 中对应

  • 替换 pom.xml 文件后,发现还是出错了,现在的错和 3.1 一样

  • [pom 配置](#4.4 使用和 Intellij 相同的 JUnit 版本)

  • 删除所有的关于 Springboot 的配置,成功运行,但是这并不是我们正真的目的,继续往下走!

  • [第2次伪解决pom配置](4.5 第2次伪解决 pom)

3.5 最终解决
  • 通过 Maven Helper 查看了依赖,发现了正真测试的时候使用的是 springboot 中的 jupiter

  • 查看了 springboot parent 中的依赖,发现以下配置

<!--parent 中的配置-->
<junit-jupiter.version>5.5.2</junit-jupiter.version>
<!--通过上面的版本映入了 一个 bom,可能是因为这个 bom 里的依赖版本造成的问题-->
<dependency>
  <groupId>org.junit</groupId>
  <artifactId>junit-bom</artifactId>
  <version>${junit-jupiter.version}</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

<!--测试项目 中的配置-->
<junit.jupiter.version>5.0.0-M4</junit.jupiter.version>
<!--将测试项目中的配置修改为,即可成功运行-->
<junit-jupiter.version>5.0.0-M4</junit.jupiter.version>
  • [pom 配置](#4.6 最终成功 pom)

4 各阶段 pom.xml 配置

4.1 最初阶段
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demoda</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demoda</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId
void register_ValidUser_SavesSuccessfully() { UserInfo user = UserInfo.builder() .username("test") .password("password") .email("test@example.com") .build(); when(userRepository.count()).thenReturn(500L); when(userRepository.findByEmail(any())).thenReturn(Optional.empty()); doNothing().when(userRepository).save(any()); assertDoesNotThrow(() -> userService.register(user)); verify(userRepository, times(1)).save(user); }报错java.lang.NoSuchMethodError: org.junit.jupiter.api.extension.ExtensionContext.getRequiredTestInstances()Lorg/junit/jupiter/api/extension/TestInstances; at org.mockito.junit.jupiter.MockitoExtension.beforeEach(MockitoExtension.java:143) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$0(TestMethodTestDescriptor.java:130) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:156) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:129) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:108) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:59) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:108) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74) 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$6(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:57) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:231) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55) Suppressed: java.lang.NullPointerException at org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:184) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterEachCallbacks$11(TestMethodTestDescriptor.java:218) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:230) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:228) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachCallbacks(TestMethodTestDescriptor.java:217) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:120) ... 31 more,请分析并解决
最新发布
08-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值