Загрузка ResourceBundle из именованных модулей

#java #internationalization #java-platform-module-system #serviceloader

#java #интернационализация #java-платформа-модуль-система #serviceloader

Вопрос:

Предположим, что модуль A (provider) содержит messages.properties , и мы хотим загрузить его как ResourceBundle из модуля B. Javadoc буквально предлагает следующий подход.

Модуль поставщика:

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

Потребительский модуль:

 module consumer {

    requires provider;
    uses MessagesProvider;
}

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

Это ОГРОМНАЯ чрезмерная разработка, но, что более важно, такой дизайн несовместим с системой плагинов. Если у вас есть несколько плагинов (поставщиков), очевидно, что они могут использовать только один и тот же интерфейс ResourceBundleProvider. Но текущая реализация ResourceBundle загружает только первую из найденных реализаций.

Интересно, в чем причина такого дизайна, если можно легко сделать что-то подобное:

 public class FooClassInProviderModule {

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

… и это работает при вызове из потребительского модуля. И это также работает с изображением JRT. Почему весь этот беспорядок с ResourceBundleProvider?

Обновить:

Хорошо, я думаю, я понял. Это не дизайн, это неправильная формулировка javadoc.

Если пакеты ресурсов развертываются в именованных модулях отдельно от вызывающего модуля, эти пакеты ресурсов необходимо загружать от поставщиков услуг ResourceBundleProvider.

Вместо этого следует сказать «Если пакеты ресурсов развернуты в именованных модулях отдельно от вызывающего модуля, и вы не знаете, где именно вам следует использовать ResourceBundleProvider, который полагается на интерфейс ServiceLoader».

Если вы знаете точный модуль, нет необходимости в ResourceBundleProvider.

Комментарии:

1. Если вы точно знаете, какой модуль содержит messages.properties, просто напишите класс в этом модуле с открытым методом, который извлекает ResourceBundle. Нет необходимости в поставщиках.