1

I'm trying to use ServiceLoader with modules system, the same way as shown in the Deploying service providers as modules header in the documentation here - click

I have the following project:

module tester.client

package tester.client;

import tester.common.Showable;

import java.util.ServiceLoader;

public class Main {

    public static void main(String[] args) {
        ServiceLoader<Showable> loader = ServiceLoader.load(Showable.class);
        loader.findFirst().orElseThrow(); //throws Exception
    }

}

module-info.java

import tester.common.Showable;

module tester.client {
    requires tester.common;
    uses Showable;
}

module tester.common

package tester.common;

public interface Showable {
    void show();
}

module-info.java

module tester.common {
    exports tester.common;
}

module tester.gui

package tester.gui;

import tester.common.Showable;

public class Window implements Showable {
    @Override
    public void show() {

    }
}

module-info.java

module tester.gui {
    requires tester.common;
    provides tester.common.Showable with tester.gui.Window;
}

THE PROBLEM:

ServiceLoader doesn't load my implementation.

  • tester.client uses Showable
  • tester.common exports Showable
  • tester.gui provides Showable with Window
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Wiktor
  • 89
  • 6
  • I can't reproduce the problem, I guess you miss tester.gui dependency in tester.client. – samabcde Jun 07 '21 at 13:53
  • @samabcde no, that would be a design flaw: _It is strongly recommended that the module does not export the package containing the service provider._ – Wiktor Jun 07 '21 at 14:28
  • I followed what you have in the post, without changing any line of code. To clarify, what I mean is maven dependency. – samabcde Jun 07 '21 at 14:34
  • @samabcde i don't use maven modules, just java jigsaw ones (as stated in tags) – Wiktor Jun 07 '21 at 14:35
  • Then I think there is something missing for the class path / module path. Please post the java command you are running. – samabcde Jun 07 '21 at 14:41
  • @samabcde I'm executing the app through Intellij IDEA, here's the exact command it executes: `C:\Java\OpenJDK\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.2\lib\idea_rt.jar=57086:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.2\bin" -Dfile.encoding=UTF-8 -p C:\Users\wikto\IdeaProjects\ModulesTest\out\production\tester.client;C:\Users\wikto\IdeaProjects\ModulesTest\out\production\tester.common -m tester.client/tester.client.Main` – Wiktor Jun 07 '21 at 14:44
  • 2
    You need module path (-p) for "C:\Users\wikto\IdeaProjects\ModulesTest\out\production\tester.gui;" – samabcde Jun 07 '21 at 14:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/233449/discussion-between-wiktor-and-samabcde). – Wiktor Jun 07 '21 at 15:01
  • 1
    The `-p` option specifies where to resolve modules, but that doesn’t imply that all of them will be loaded. You specified `tester.client` with `-m` and its only dependency is `tester.common`. To ensure that additional modules, i.e. `tester.gui`, get loaded, you need to specify `--add-modules`. – Holger Jun 07 '21 at 16:30

1 Answers1

0

It turned out the problem is IDE-specific. As my IDE (Intellij IDEA) has its own additional modules system, I needed to add tester.gui module as a dependency of tester.client module.

Solution provided by @samabcde

Wiktor
  • 89
  • 6