Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm adding module-info.javas to 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.

Given this, I created these module definitions:

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;
}

They might not be complete, but they are complete enough so that when my application starts, it fails with this error:

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

which is throw when no handler managed to 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 + "'");
}

The reason why that is happening is that HANDLERS is empty. HANDLERS is loaded 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));
    } 

but with the module definitions quoted above, ServiceLoader.load(IkonHandler.class, classLoader) finds no service providers.

What am I missing?

like image 523
pupeno Avatar asked Sep 19 '25 11:09

pupeno


1 Answers

What I was missing was requiring fontawesome5 in the module-info.java of my application:

requires org.kordamp.ikonli.fontawesome5;
like image 102
pupeno Avatar answered Sep 22 '25 01:09

pupeno



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!