使用新的Java模块系统加载服务提供程序我还缺少什么?

我正在将module-info.java添加到Ikonli软件包中,我的服务类遇到了麻烦。 ikonli-core定义了一个名为IkonHandler的接口。 ikonli-fontawesome5-pack有一个名为FontAwesomeSolidIkonHandlerIkonHandler 服务提供商 。 这些服务产品由ikonli-javafxIkonResolver

鉴于此,我创建了这些模块定义:

 module org.kordamp.ikonli.core { exports org.kordamp.ikonli; } module org.kordamp.ikonli.javafx { exports org.kordamp.ikonli.javafx; uses org.kordamp.ikonli.IkonHandler; requires javafx.graphics; requires org.kordamp.ikonli.core; } module org.kordamp.ikonli.fontawesome5 { exports org.kordamp.ikonli.fontawesome5; provides org.kordamp.ikonli.IkonHandler with org.kordamp.ikonli.fontawesome5.FontAwesomeBrandsIkonHandler, org.kordamp.ikonli.fontawesome5.FontAwesomeRegularIkonHandler, org.kordamp.ikonli.fontawesome5.FontAwesomeSolidIkonHandler; requires org.kordamp.ikonli.core; requires org.kordamp.jipsy; } 

它们可能不完整,但它们足够完整,以便在我的应用程序启动时,它会因此错误而失败:

 java.lang.UnsupportedOperationException: Cannot resolve 'fas-user' 

没有处理程序设法加载图标时抛出:

 public IkonHandler resolveIkonHandler(String value) { requireNonNull(value, "Ikon description must not be null"); for (IkonHandler handler : HANDLERS) { if (handler.supports(value)) { return handler; } } throw new UnsupportedOperationException("Cannot resolve '" + value + "'"); } 

发生这种情况的原因是HANDLERS是空的。 HANDLERS 在启动时通过以下代码加载 :

  ClassLoader classLoader = IkonResolver.class.getClassLoader(); ServiceLoader loader = ServiceLoader.load(IkonHandler.class, classLoader); for (IkonHandler handler : loader) { HANDLERS.add(handler); handler.setFont(Font.loadFont(classLoader.getResource(handler.getFontResourcePath()).toExternalForm(), 16)); } 

但是使用上面引用的模块定义, ServiceLoader.load(IkonHandler.class, classLoader)找不到服务提供者。

我错过了什么?

我缺少的是在我的应用程序的module-info.java中需要fontawesome5

 requires org.kordamp.ikonli.fontawesome5; 

“我的应用程序不需要fontawesome5模块。” 您的应用不需要它。 实际上,您的应用不应该要求它。 你错过了使用/提供的点。

编辑通过将提供程序放在模块路径上并观察模块系统开始工作,可以使提供程序可用。 您的ikonli.javafx模块使用IkonHandler接口,您的ikonli.fontawesome5模块提供IkonHandler接口的实现。 这就是所有模块系统需要将它们绑定在一起。 ikonli.javafx要求ikonli.fontawesome5是错误的。 ikonli.fontawesome5甚至不应该导出它导出的包,因为这允许任何需要ikonli.fontawesome5的人直接访问FontAwesomeBrandsIkonHandler等提供者类。