Loading ResourceBundle from named modules

525 Views Asked by At

Let's suppose that module A (provider) contains messages.properties and we want to load it as ResourceBundle from module B. Javadoc literally suggests the following approach.

Provider module:

module provider {
    exports provider;
    exports provider.spi;
    provides MessagesProvider with MessagesProviderImpl;
}

package provider.spi;
public interface MessagesProvider extends ResourceBundleProvider {}

package provider;
public class MessagesProviderImpl extends AbstractResourceBundleProvider implements MessagesProvider {

    public MessagesProviderImpl() {
        super("java.properties");
    }

    protected String toBundleName(String baseName, Locale locale) {
        return super.toBundleName(baseName.toLowerCase(), locale);
    }
}

Consumer module:

module consumer {

    requires provider;
    uses MessagesProvider;
}

ResourceBundle bundle = ResourceBundle.getBundle("provider.Messages");

This is HUGE over-engineering but what's more important such design doesn't compatible with plugin system. If you have multiple plugins (providers) obviously they can only share the same ResourceBundleProvider interface. But current ResourceBundle implementation only loads the first of found implementations.

I wonder whats the reason of such design if one can easily do something like that:

public class FooClassInProviderModule {

    public ResourceBundle getBundle(Locale locale) {
        return ResourceBundle.getBundle(LOCAL_PATH, locale, FooClassInProviderModule.class.getModule());
    }
}

... and it works when called from consumer module. And it also works form JRT image. Why all the mess with ResourceBundleProvider?

UPDATE:

Ok, I think I got it. It not design, it javadocs incorrect wording.

If resource bundles are deployed in named modules separate from the caller module, those resource bundles need to be loaded from service providers of ResourceBundleProvider.

Instead it should say "If resource bundles are deployed in named modules separate from the caller module and you don't know where exactly you should ResourceBundleProvider which relies on ServiceLoader interface".

If you know exact module there's no need to ResourceBundleProvider.

0

There are 0 best solutions below