--- a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java Thu Jun 01 18:48:56 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java Thu Jun 01 14:52:53 2017 -0700
@@ -216,16 +216,17 @@
* the caller module, those resource bundles need to be loaded from service
* providers of {@link ResourceBundleProvider}. The caller module must declare
* "{@code uses}" and the service interface name is the concatenation of the
- * base name of the bundles and the string "{@code Provider}". The
+ * package name of the base name, string "{@code .spi.}", the simple class
+ * name of the base name, and the string "{@code Provider}". The
* <em>bundle provider modules</em> containing resource bundles must
* declare "{@code provides}" with the service interface name and
* its implementation class name. For example, if the base name is
* "{@code com.example.app.MyResources}", the caller module must declare
- * "{@code uses com.example.app.MyResourcesProvider;}" and a module containing resource
- * bundles must declare "{@code provides com.example.app.MyResourcesProvider
+ * "{@code uses com.example.app.spi.MyResourcesProvider;}" and a module containing resource
+ * bundles must declare "{@code provides com.example.app.spi.MyResourcesProvider
* with com.example.app.internal.MyResourcesProviderImpl;}"
* where {@code com.example.app.internal.MyResourcesProviderImpl} is an
- * implementation class of {@code com.example.app.MyResourcesProvider}.</li>
+ * implementation class of {@code com.example.app.spi.MyResourcesProvider}.</li>
* <li>If you want to use non-standard formats in named modules, such as XML,
* {@link ResourceBundleProvider} needs to be used.</li>
* <li>The {@code getBundle} method with a {@code ClassLoader} may not be able to
@@ -243,9 +244,10 @@
*
* The {@code getBundle} factory methods load service providers of
* {@link ResourceBundleProvider}, if available, using {@link ServiceLoader}.
- * The service type is designated by {@code basename+"Provider"}. For
+ * The service type is designated by
+ * {@code <package name> + ".spi." + <simple name> + "Provider"}. For
* example, if the base name is "{@code com.example.app.MyResources}", the service
- * type is {@code com.example.app.MyResourcesProvider}.
+ * type is {@code com.example.app.spi.MyResourcesProvider}.
* <p>
* In named modules, the loaded service providers for the given base name are
* used to load resource bundles. If no service provider is available, or if
@@ -923,7 +925,12 @@
* <p> Resource bundles in named modules may be encapsulated. When
* the resource bundle is loaded from a provider, the caller module
* must have an appropriate <i>uses</i> clause in its <i>module descriptor</i>
- * to declare that the module uses implementations of {@code "baseName"Provider}.
+ * to declare that the module uses implementations of
+ * {@code <package name> + ".spi." + <simple name> + "Provider"}.
+ * Otherwise, it will load the resource bundles that are local in the
+ * given module or that are visible to the class loader of the given module
+ * (refer to the <a href="#bundleprovider">Resource Bundles in Named Modules</a>
+ * section for details).
* When the resource bundle is loaded from the specified module, it is
* subject to the encapsulation rules specified by
* {@link Module#getResourceAsStream Module.getResourceAsStream}.
@@ -958,20 +965,17 @@
* <p> Resource bundles in named modules may be encapsulated. When
* the resource bundle is loaded from a provider, the caller module
* must have an appropriate <i>uses</i> clause in its <i>module descriptor</i>
- * to declare that the module uses implementations of {@code "baseName"Provider}.
+ * to declare that the module uses implementations of
+ * {@code <package name> + ".spi." + <simple name> + "Provider"}.
+ * Otherwise, it will load the resource bundles that are local in the
+ * given module or that are visible to the class loader of the given module
+ * (refer to the <a href="#bundleprovider">Resource Bundles in Named Modules</a>
+ * section for details).
* When the resource bundle is loaded from the specified module, it is
* subject to the encapsulation rules specified by
* {@link Module#getResourceAsStream Module.getResourceAsStream}.
*
* <p>
- * If the given {@code module} is a named module, this method will
- * load the service providers for {@link java.util.spi.ResourceBundleProvider}
- * and also resource bundles that are local in the given module or that
- * are visible to the class loader of the given module (refer to the
- * <a href="#bundleprovider">Resource Bundles in Named Modules</a> section
- * for details).
- *
- * <p>
* If the given {@code module} is an unnamed module, then this method is
* equivalent to calling {@link #getBundle(String, Locale, ClassLoader)
* getBundle(baseName, targetLocale, module.getClassLoader()} to load
@@ -1070,8 +1074,10 @@
* Resource bundles in a named module are private to that module. If
* the caller is in a named module, this method will find resource bundles
* from the service providers of {@link java.util.spi.ResourceBundleProvider}
- * and also find resource bundles that are in the caller's module or
- * that are visible to the given class loader.
+ * if any. Otherwise, it will load the resource bundles that are visible to
+ * the given {@code loader} (refer to the
+ * <a href="#bundleprovider">Resource Bundles in Named Modules</a> section
+ * for details).
* If the caller is in a named module and the given {@code loader} is
* different than the caller's class loader, or if the caller is not in
* a named module, this method will not find resource bundles from named
@@ -1883,8 +1889,15 @@
private static Class<ResourceBundleProvider>
getResourceBundleProviderType(String baseName, ClassLoader loader)
{
- // Look up <baseName> + "Provider"
- String providerName = baseName + "Provider";
+ // Look up <packagename> + ".spi." + <name>"Provider"
+ int i = baseName.lastIndexOf('.');
+ if (i <= 0) {
+ return null;
+ }
+
+ String name = baseName.substring(i+1, baseName.length()) + "Provider";
+ String providerName = baseName.substring(0, i) + ".spi." + name;
+
// Use the class loader of the getBundle caller so that the caller's
// visibility of the provider type is checked.
return AccessController.doPrivileged(