oberlies
oberlies

Reputation: 11723

Junit 5 tests don't launch in Eclipse due to NoClassDefFoundError: TestEngine

(There was no question for this problem in stackoverflow, so I decided to share question & solution here.)

I wanted to migrate my Spring Boot project from JUnit 4 to JUnit 5, so I added the new API as dependency and removed the old the ones:

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
    </dependency>

I wanted to do a full migration of my project, so I explicitly excluded everything from JUnit 4, and also did not include the junit-vintage-engine (as recommended in the official migration guide).

Then, I did the various changes to make the tests compile, like replacing @Before with @BeforeEach and organizing imports. All in all, this was pretty straightforward.

But running the tests in Eclipse caused some trouble:

After I while, I figured out that the test execution had printed a stack trace in the console:

java.lang.NoClassDefFoundError: org/junit/platform/engine/TestEngine
    at org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry.loadTestEngines(ServiceLoaderTestEngineRegistry.java:35)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:87)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:67)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.<init>(JUnit5TestLoader.java:34)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:456)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createRawTestLoader(RemoteTestRunner.java:370)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.createLoader(RemoteTestRunner.java:365)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.defaultInit(RemoteTestRunner.java:309)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.init(RemoteTestRunner.java:224)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:208)
Caused by: java.lang.ClassNotFoundException: org.junit.platform.engine.TestEngine
    at java.net.URLClassLoader.findClass(URLClassLoader.java:444)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:486)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:378)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
    ... 14 more

This pointed me to the root cause of the problem (see answer below)...

Upvotes: 3

Views: 15105

Answers (1)

oberlies
oberlies

Reputation: 11723

The problem was that I was missing the dependency to the engine library:

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

Then, the tests run like a charm in Eclipse.

Migration blogs like https://dev.to/martinbelev/how-to-enable-junit-5-in-new-spring-boot-project-29a8 do mention this dependency, but I primarily worked with the JUnit 5 documentation, and somehow I must have overlooked this important piece of information there...

Upvotes: 17

Related Questions