0

In IntelliJ/Maven I want to work with Java9 / modules and the ServiceLoader. I built a simple 2 module project. Using maven the ServiceLoader.load( ...) cannot find the implementation of the HelloInterface.class. Why?

I created the project via IntelliJ by first adding the 2 modules. Rebuilding the project works fine. Clean/installing via Maven also works fine - well, the unit test fails ;-(

UPDATE 1: Running with IntelliJ is OK due to putting the module-info.java right under the sources root. I compile using the "Rebuild project".

How can I use this 2 module project with the ServiceLoader with Maven?

My simple project struture is:

enter image description here

pom.xml:

<build>
<plugins>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>14</source>
        <target>14</target>
    </configuration>
</plugin>
</plugins>
</build>
<modules>
    <module>java9.com.hello</module>
    <module>java9.com.hello.client</module>
</modules>

File: module java9.com.hello / src / main / java / module-info.jar

module java9.com.hello {
    exports com.hello;
    exports com.hello.services;
    provides com.hello.services.HelloInterface with com.hello.services.HelloWorldIntefaceImpl;
}

File: module java9.com.hello / com.hello.services.HelloInterface.java

public interface HelloInterface {
    String sayHello();
}

File: module java9.com.hello / com.hello.services.HelloWorldIntefaceImpl.java

public class HelloWorldIntefaceImpl implements HelloInterface {
    public String sayHello() {
        String helloString = "Hello world by Inteface!";
        System.out.println( helloString);
        return helloString;
    }
}

File: module java9.com.hello / pom.xml (without the boilerplate)

<parent>
    <artifactId>jdk-new-features</artifactId>
    <groupId>org.example</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>java9.com.hello</artifactId>

File: module java9.com.hello.client / src / main / java / module-info.jar. This file is giving the compiler error.

module java9.com.hello.client {
    requires java9.com.hello; // <==== gives the ERROR
    uses com.hello.services.HelloInterface;
}

File: module java9.com.hello.client / com.hello.client.HelloWorldClient.java

public class HelloWorldClient {
    public static void main (String arg[]) {
        HelloWorld hello = new HelloWorld();
        System.out.println(hello.sayHelloWorld());
        Iterable<HelloInterface> services = ServiceLoader.load(HelloInterface.class);
        HelloInterface service = services.iterator().next();
        service.sayHello();
    }
    public String callService() {
        Iterable<HelloInterface> services = ServiceLoader.load(HelloInterface.class);
        HelloInterface service = services.iterator().next();
        return service.sayHello();
    }
}

The pom.xml is: module java9.com.hello.client / pom.xml:

<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>java9.com.hello</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Unit test file: module java9.com.hello.client / com.hello.client.HelloWorldClientTest.java

public class HelloWorldClientTest {
    @Test
    public void testModuleInterfaceImplementation() {
        HelloWorldClient helloWorldClient = new HelloWorldClient();
        assertEquals( "Hello world by Inteface!", helloWorldClient.callService());
    }
}
tm1701
  • 7,307
  • 17
  • 79
  • 168
  • 1
    Please add the pom file of the `java9.com.hello` module. Furthermore if you really like to use modules your `module-info.java` has to be located into `src/main/java` and to use a service loader you have to define `META-INF/services/...` files which looks like you don't have done yet. – khmarbaise Aug 09 '20 at 16:34
  • Thank you for your suggestions, I added the trivial pom.xml. I will work on your suggestions. – tm1701 Aug 10 '20 at 06:22
  • 1
    I don't think you need the META-INF/services files when you have modules and a provides directive. On the other hand you do need to export com.hello.services (you only export com.hello). Plus you need to run with modules enabled or the provides statement won't help. – ewramner Aug 10 '20 at 06:29
  • „*…the compiler error…*“ — Please edit your question to include the details of „*the compiler error*“? TIA. – deduper Sep 20 '20 at 17:03
  • See the title of the question and the first paragraph. – tm1701 Sep 20 '20 at 17:42

0 Answers0