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

What else am I missing to load service providers using the new Java module system?

我要将 module-info.java 添加到 Ikonli packages and I'm running into trouble with their service classes. ikonli-core defines an interface called IkonHandler. ikonli-fontawesome5-pack has a service provider for the IkonHandler called FontAwesomeSolidIkonHandler. These service prodivers are used by ikonli-javafx's IkonResolver

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

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'

当没有处理程序设法 load the icon:

时抛出
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 是空的。 HANDLERSloaded at startup by this code:

    ClassLoader classLoader = IkonResolver.class.getClassLoader();
    ServiceLoader<IkonHandler> 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) 找不到服务提供者。

我错过了什么?

"My app was not requiring the the fontawesome5 module." 您的应用不需要它。事实上,您的应用程序不应该需要它。你错过了 uses/provides.

的要点

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

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

requires org.kordamp.ikonli.fontawesome5;