<i18n dev> ResourceBundleProvider(s) design

Peter Levart peter.levart at gmail.com
Thu Aug 4 09:21:31 UTC 2016


Hi,

I would like to ask about why java.util.spi.ResourceBundleProvider is 
designed they way it is. I'm questioning the design of the following 
part of specification:

     "The provider service type is determined by {@code 
basename+"Provider"}."

Why is that necessary? It requires that provider service types are 
specialized per bundle base name. Each bundle base name requires a 
specific ResourceBundleProvider service subtype. This seems superfluous 
with the API point that ResourceBundleProvider declares:

public interface ResourceBundleProvider {
     /**
      * Returns a {@code ResourceBundle} for the given bundle name and 
locale.
      * This method returns {@code null} if there is no {@code 
ResourceBundle}
      * found for the given parameters.
      *
      *
      * @param baseName
      *        the base bundle name of the resource bundle, a fully
      *        qualified class name
      * @param locale
      *        the locale for which the resource bundle should be loaded
      * @return the ResourceBundle created for the given parameters, or 
null if no
      *         {@code ResourceBundle} for the given parameters is found
      */
     public ResourceBundle getBundle(String baseName, Locale locale);
}

.., the getBundle method takes a 'baseName' parameter. Why does it need 
such parameter when the service type already implies the bundle base name?

What is the rationale behind such design?

Who in this design (which module) is meant to define the service type 
for a particular bundle base name? The consuming module or the providing 
module? In case it is the consuming module, then the providing module 
will have an explicit dependency on the consuming module, which goes 
against the aim of service providers that provide services to multiple 
modules. If the providing module declares the service type, then the 
consuming module will have an explicit dependency on the providing 
module, which also defeats the purpose of service provider's implicit 
coupling. So the only thing left is to define the service types for each 
particular bundle base name in a special module that consumers and 
providers depend on. But this just goes against the aim of 
encapsulation. The bundle name should be a private contract between an 
unknown consumer and unknown provider - no other module(s) should be 
involved.

A better design would be to not require that service type name be 
derived from bundle base name and have a constant service type 
regardless of bundle base name: java.util.spi.ResourceBundleProvider. So 
all providers would be polled for a particular bundle name and only the 
ones responsible for the particular name would respond with a non-null 
ResourceBundle instance.

But this would present a problem in resolving of the transitive closure 
of dependent observable modules as it would pull-in all modules that 
provide bundles and not only those that provide bundles for required 
names. So without some additional resolution constraints this would 
present a problem. So I wonder whether the addition of 
ResourceBundleProvider service provider interface to ResourceBundle 
resolution process is a good idea at all. Now that resources are not 
encapsulated any more, " java.properties" format of bundles is 
resolvable among modules and "java.class" format of bundles too, when 
appropriate packages are exported.

It feels that providing resource bundles via service provider 
infrastructure is too much fuss so no-one will use this mechanism if 
existing mechanism is more than adequate.

Comments?

Regards, Peter




More information about the i18n-dev mailing list