javajbosswildflyjunit5

Junit5 Wildfly TestEngine implementation is found via Class.forName but not found using the ClassLoader


I have a WAR deployed on WildFly that depends on a module where JUnit 5 JARs are located. I keep getting this exception:

[Cannot create Launcher without at least one TestEngine; consider adding an engine implementation JAR to the classpath]: org.junit.platform.commons.PreconditionViolationException: Cannot create Launcher without at least one TestEngine; consider adding an engine implementation JAR to the classpath

The code that I'm using for testing this is

@RestController
@RequestMapping("/Paolo")
public class HelloController {
    Logger logger = LoggerFactory.getLogger(HelloController.class);
    @GetMapping("/hello")
    String hello() throws ClassNotFoundException {
       Class.forName("org.junit.jupiter.engine.JupiterTestEngine"); // no exception thrown
       Iterable<TestEngine> testEngines = ServiceLoader.load(TestEngine.class,
                ClassLoaderUtils.getDefaultClassLoader()); // method used by junit to found the TestEngineImplementation JupiterTestEngine is the only real implementation
       logger.info("testEngines: {}", testEngines.iterator().hasNext()); // false
       return "Hi";
   }
}

If instead of having JUnit 5 JARs in the module, I put them in the WEB-INF/lib of the WAR, everything works just fine.

I understood from here that modules are loaded and put on the classpath of the WAR.

Why, if I move the JARs under WEB-INF/lib, it works? What is the difference?

You can find the complete example here, the correct branch is junit5.


Solution

  • In your jboss-deployment-structure.xml you're missing services="import" on the module. From your example, it would look something like:

    <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
    <ear-subdeployments-isolated>false</ear-subdeployments-isolated>
    <deployment>
        <dependencies>
            <module name="org.jboss.vfs" />
            <module name="jar" services="import" />
        </dependencies>
    </deployment>
    </jboss-deployment-structure>
    

    I still got some errors with that, but they might just be simply missing a dependency. I didn't really dig into it.