1

I am learning Java 9 Module by reading the book "Modular Programming in Java 9". In chapter 7, Introducing services, at page 201, I followed the steps by the book to create a simple project using service. I will post the code below or you can visit the project on github.

  1. service

module name: packt.sortutil

class full name: packt.util.SortUtil

public interface SortUtil {
    <T extends Comparable> List<T> sortList(List<T> list);
}

2. providers class full name: packt.util.impl.bubblesort.BubbleSortUtilImpl: code:

package packt.util.impl.bubblesort;
public class BubbleSortUtilImpl implements SortUtil 
...

module-info.java

module packt.sort.bubblesort {
    requires packt.sortutil;
    provides packt.util.SortUtil with packt.util.impl.bubblesort.BubbleSortUtilImpl;
}

There is also packt.util.impl.javasort.JavaSortUtilImpl with the only difference of a different implementation.

  1. consumer

module-info.java:

module packt.addressbook {
    requires packt.sortutil;
    uses packt.util.SortUtil; 
}

code:

Iterable<SortUtil> sortUtils = ServiceLoader.load(SortUtil.class);
for (SortUtil sortUtil : sortUtils){
    System.out.println("Found an instance of SortUtil");
    sortUtil.sortList(contacts);
}

When I run consumer, it should be: enter image description here

Note the highlighted area, where 2 implementations are found. Also, the names are sorted by the last name.

But for my program, it is:

2月 03, 2019 12:12:55 上午 packt.addressbook.Main main

INFO: Address book viewer application: Started

2月 03, 2019 12:12:56 上午 packt.addressbook.Main main

INFO: Address book viewer application: Completed

[Edsger Dijkstra, Raid Black]

Notice there are no "Found an instance of SortUtil" and the names are not sorted. So it appears as if there are no implementations registered with the service.

Where did it go wrong? Thanks.

Naman
  • 27,789
  • 26
  • 218
  • 353
fall
  • 984
  • 11
  • 33
  • 2
    You also need to ensure that both your module with implementation(e.g. `packt.sort.bubblesort `) are resolved on the modulepath while you're executing your consumer code. Check [this link on how](https://stackoverflow.com/questions/48339598/list-the-modules-resolved-during-the-application-startup) to do it. – Naman Feb 03 '19 at 08:10

1 Answers1

0

What I did

@nullpointer's suggestion is helpful. I used java --module-path out --module packt.addressbook/packt.addressbook.Main to debug the see the module path, and found out:

root packt.addressbook file:///D:/ebooks/Modular%20Programming%20in%20Java%209/
ce-code/p205_Implementing_sorting_services/out/production/packt.addressbook/
packt.addressbook requires packt.sortutil file:///D:/ebooks/Modular%20Programmi
n%20Java%209/practice-code/p205_Implementing_sorting_services/out/production/pa
rtutil/
packt.addressbook requires java.logging jrt:/java.logging
packt.addressbook requires packt.contact file:///D:/ebooks/Modular%20Programmin
%20Java%209/practice-code/p205_Implementing_sorting_services/out/production/pac
tact/
packt.contact requires java.xml jrt:/java.xml
...

Module packt.sort.bubblesort and packt.sort.javasort were not present in the module path. Then I checked the output folder and saw that these 2 provider modules' were not compiled. I figured out that the reason is these 2 modules werenot readable by any other modules and therefore omitted during compilation.

When I used the command D:\programs\java\jdk-11.0.2\bin\javac -d out --module-source-path .\*\src -m packt.addressbook, it looks for modules that modulepackt.addressbook dependent on, including service module packt.sortutil, but since packt.sortutil and other modules do not depend on the 2 service modules,packt.sort.bubblesort and packt.sort.javasort, they are omitted. Actually, they depend on the service module instead.


Solutions

So I changed to command to manually compile these 2 modules: javac -d out --module-source-path .\*\src -m packt.addressbook,packt.sort.bubblesort,packt.sort.javasort. And it is fixed now.

There is another project that uses maven to the fix this issue. The consumer module(packt.addressbook in my example)'s POM depends on the provider module(packt.sort.bubblesort and packt.sort.javasort in my example):

<dependency>
    <groupId>javax0</groupId>
    <artifactId>Provider</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

I am not sure if this is the best practice, though.


Follow up

If someone knows how to manually add modules for compilation or automatically discover provider modules 'providing` a service module for compilation inside a IDE like IntelliJ IDEA, please let me know.

fall
  • 984
  • 11
  • 33