I can't run JUnit 5.9.x tests in Eclipse 2023-09 (4.29.0)

2.3k Views Asked by At

Hi I've start with start.spring.io just like below enter image description here

and I was trying to check if test is okay or not by default. enter image description here enter image description here

but it wasn't even start to it. and I got this error in console instead of test results.

java.lang.NoSuchMethodError: 'java.util.Set org.junit.platform.engine.TestDescriptor.getAncestors()'
    at org.junit.platform.launcher.core.StackTracePruningEngineExecutionListener.getTestClassNames(StackTracePruningEngineExecutionListener.java:50)
    at org.junit.platform.launcher.core.StackTracePruningEngineExecutionListener.executionFinished(StackTracePruningEngineExecutionListener.java:39)
    at org.junit.platform.launcher.core.DelegatingEngineExecutionListener.executionFinished(DelegatingEngineExecutionListener.java:46)
    at org.junit.platform.launcher.core.OutcomeDelayingEngineExecutionListener.reportEngineFailure(OutcomeDelayingEngineExecutionListener.java:83)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:203)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:169)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:93)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:58)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:141)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:57)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:94)
    at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:52)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:70)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

I googled. people said that it was seemed that related with jupiter-api version. so I added some dependencies like this. but it didn't work.

// build.gradle
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.1.3'
    id 'io.spring.dependency-management' version '1.1.3'
}

group = 'hello'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '17'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    
    
    testImplementation('org.junit.jupiter:junit-jupiter-api:5.9.3') /// added version
    testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.9.3') /// added version
}

tasks.named('test') {
    useJUnitPlatform()
}

I also tried in different way. I added Java Build Path on my Eclipse IDE but it didn't work too.
(right click on my project > Properties > Java Build Path
> Modulepath(already tried classpath too.) > Add Library > JUnit

I didn't see same case about JUnit error with 'java.util.Set org.junit.platform.engine.TestDescriptor.getAncestors()'.
so I'm confused now. please help.

3

There are 3 best solutions below

0
howlger On BEST ANSWER

This seems an issue of Eclipse Buildship with JUnit less than 5.10.0 and Eclipse 2023-09 (4.29) which I reported here:

Eclipse Buildship issue #1265: NoSuchMethodError when running a JUnit 5.9.3 test in Eclipse 2023-09 (4.29)

Workarounds:

  • In build.gradle, add the dependency testImplementation 'org.junit.platform:junit-platform-launcher:1.9.3' or
  • Upgrade to JUnit 5.10.0: testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
  • See Daniele Repici's answer for a workaround without changing build.gradle

Cause:

It seems Buildship does not choose the corresponding junit-platform-launcher (as m2e seems to do; at least this issue cannot be reproduced with Maven), but uses the junit-platform-launcher version that is shipped with Eclipse. And in Eclipse 4.29 junit-platform-launcher has been upgraded to 1.10.0. But org.junit.platform:junit-platform-launcher:1.10.0 calls org.junit.platform.engine.TestDescriptor.html::getAncestors which has been introduced in org.junit.platform:junit-platform-engine:1.10.0 and which is missing in org.junit.platform:junit-platform-engine:1.9.3 in JUnit 5.9.3.

0
user and On

I think this is only about Eclipse 2023-09 and Junit compatibility. @howlger asked minimal example to confirm, so here is it. I've created new gradle project(wrapper, version 8.1.1) with standard source layout.

build.gradle

apply plugin: 'java'
java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}
repositories {
    mavenCentral()
}
compileJava {
    options.encoding = "UTF-8"
}
compileTestJava {
    options.encoding = "UTF-8"
}

dependencies {    
    testImplementation("org.junit.jupiter:junit-jupiter:5.9.3")
    testImplementation("org.junit.vintage:junit-vintage-engine:5.9.3")
}

settings.gradle

rootProject.name = 'JunitBug'

StubTest.java

package com.junitbug;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

    class StubTest {
        @Test
        void test() {
            boolean b = true;
            assertTrue(b);
        }
    }

After test run in Eclipse I have the same exception:

java.lang.NoSuchMethodError: 'java.util.Set org.junit.platform.engine.TestDescriptor.getAncestors()'
    at org.junit.platform.launcher.core.StackTracePruningEngineExecutionListener.getTestClassNames(StackTracePruningEngineExecutionListener.java:50)
    at org.junit.platform.launcher.core.StackTracePruningEngineExecutionListener.executionFinished(StackTracePruningEngineExecutionListener.java:39)
    at org.junit.platform.launcher.core.DelegatingEngineExecutionListener.executionFinished(DelegatingEngineExecutionListener.java:46)
    at org.junit.platform.launcher.core.OutcomeDelayingEngineExecutionListener.reportEngineFailure(OutcomeDelayingEngineExecutionListener.java:83)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:203)
    ....

Updating junit version to 5.10.0 in build.gradle fixed the issue. Note that "gradlew test" works fine in both case.

1
Daniele Repici On

I found a nice workaround that doesn't require you to change the project.

This comes useful when modifying your project's dependencies is not an option (e.g. if you'd have to justify to the rest of your team using other kinds of IDE why you would override Spring Boot's JUnit and/or if you are working on 50+ different projects).

In Eclipse, go to Window --> Preferences --> Gradle. In the Advanced Options section, under Program Arguments, add: -Pjunit-jupiter.version=5.10.0.

Click Apply.

This has the same effect as adding ext[junit-jupiter.version]=5.10.0 to your build.gradle file, but saves you from modifying your project and will work for all your projects.

This works because of the way Spring Boot Management plugin works. The Spring Boot dependencies BOM uses placeholders for all its versions. You can find the placeholder names in Maven by clicking on the POM link.