我通过阅读这本书“Modular Programming in Java 9”学习Java 9模块。在第7章,在第201页介绍服务,我跟着经书步骤来创建使用服务的简单项目。我会后下面的代码,或者您可以访问该项目上github。
模块名称:packt.sortutil
类全名:packt.util.SortUtil
public interface SortUtil {
<T extends Comparable> List<T> sortList(List<T> list);
}
2.供应商类全名:packt.util.impl.bubblesort.BubbleSortUtilImpl:代码:
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;
}
还有一个不同的实现的,唯一的区别packt.util.impl.javasort.JavaSortUtilImpl
。
module-info.Java:
module packt.addressbook {
requires packt.sortutil;
uses packt.util.SortUtil;
}
码:
Iterable<SortUtil> sortUtils = ServiceLoader.load(SortUtil.class);
for (SortUtil sortUtil : sortUtils){
System.out.println("Found an instance of SortUtil");
sortUtil.sortList(contacts);
}
请注意突出显示的区域,其中2个实现被发现。此外,名称由姓氏排序。
但对于我的程序,它是:
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]
请注意,没有“找到一个SortUtil的实例”和名称进行排序。因此,它看起来好像没有注册该服务的实现。
这有什么错?谢谢。
我做了什么
@空指针的建议是有帮助的。我用java --module-path out --module packt.addressbook/packt.addressbook.Main
调试看到的模块路径,并发现:
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
...
模块packt.sort.bubblesort
和packt.sort.javasort
不存在于该模块的路径。然后,我检查了输出文件夹,看到这2个提供商模块没有编制。我想通了,其原因是这些2个模块都不在任何其它模块可读因此编译期间删去。
当我用命令D:\programs\java\jdk-11.0.2\bin\javac -d out --module-source-path .\*\src -m packt.addressbook
,它将查找modulepackt.addressbook
依赖模块,包括服务模块packt.sortutil
,但由于packt.sortutil
和其他模块不依赖于2个服务模块,packt.sort.bubblesort
和packt.sort.javasort
,它们被省略。其实,他们赖以生存的服务模块来代替。
解决方案
因此,我改变到命令手动编译这些2个模块:javac -d out --module-source-path .\*\src -m packt.addressbook,packt.sort.bubblesort,packt.sort.javasort
。而现在是固定的。
有一个使用Maven来修复这个问题的另一个project。消费者模块(在我的例子packt.addressbook
)的POM取决于提供商模块(packt.sort.bubblesort
和packt.sort.javasort
在我的例子)上:
<dependency>
<groupId>javax0</groupId>
<artifactId>Provider</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
我不知道这是否是最好的做法,虽然。
跟进
如果有人知道如何手动添加模块编译或自动发现提供商模块的providing`编译服务模块像IntelliJ IDEA的一个IDE中,请让我知道。