Java 9: ServiceLoader doesn't load Test implementation from Test sources (Module)

Viewed 867

I'm using Java9 Module system (running on openjdk11)

I have

  • migrated from Java8 and the code contained classes that made use of the ServiceLoader mechanism.
  • a unit test for this class which tries to load two test service implementations

  • the test implementations are listed in META-INF/services file

src/main/example/Service.java

public interface Service {
  public static List<Service> loadServices(){
    return StreamSupport.stream(ServiceLoader.load(Service.class).spliterator(),false)                                       
                        .collect(Collectors.toList());
   }
}

and a src/main/module-info.java

module example {
  uses example.Service;
  exports example;
}

and I have a unit test like this

src/main/example/ServiceTest.java

public ServiceTest {
  @Test
  void loadServices_should_find_TestServices{
    List<Service> services = Service.loadServices();
    assertEquals(2, services.size());
  }
}

and I have two test services in the test source:

src/main/example/TestService1.java

public TestService1 implements Service {}

src/main/example/TestService2.java

public TestService2 implements Service {}

src/test/resources/META-INF/services/example.Service

example.TestService1
example.TestService2

I'm using the maven-surefire-plugin 3.0.0-M3 without any specific configuration

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-failsafe-plugin</artifactId>
  <version>3.0.0-M3</version>
</plugin>

which properly patches the example module (from surefireargs file)

--patch-module example="D:\\git\\example\\target\\test-classes"

When I execute the test in IntelliJ directly, the test run successfully, finding two services. However, when I build the module in maven and the test is executed by surefire, it doesn't find the services and the test fails.

How am I supposed to configure surefire to find the TestServices located in the test sources? I can not define a "provides ..." declaration in the module info as they are test services. What am I doing wrong?

1 Answers

I found a workaround, which I don't really consider an actual solution to the problem: Disabling the ModulePath in surefire, reverting back to ClassPath:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <useModulePath>false</useModulePath>
  </configuration>
</plugin>
Related