diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java index c5d8e7091f..27762ba049 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,8 +115,9 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage /** * Set the default charset to use for parsing properties files. * Used if no file-specific charset is specified for a file. - *
Default is none, using the {@code java.util.Properties} - * default encoding: ISO-8859-1. + *
The effective default is the {@code java.util.Properties} + * default encoding: ISO-8859-1. A {@code null} value indicates + * the platform default encoding. *
Only applies to classic properties files, not to XML files. * @param defaultEncoding the default charset */ diff --git a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java index dad357807b..0bfa58cdad 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/support/ResourceBundleMessageSource.java @@ -58,6 +58,17 @@ import org.springframework.util.ClassUtils; * Note that the JDK's standard ResourceBundle treats dots as package separators: * This means that "test.theme" is effectively equivalent to "test/theme". * + *
On the classpath, bundle resources will be read with the locally configured
+ * {@link #setDefaultEncoding encoding}: by default, ISO-8859-1; consider switching
+ * this to UTF-8, or to {@code null} for the platform default encoding. On the JDK 9+
+ * module path where locally provided {@link ResourceBundle.Control} handles are not
+ * supported, this MessageSource always falls back to {@link ResourceBundle#getBundle}
+ * retrieval with the platform default encoding: UTF-8 with a ISO-8859-1 fallback on
+ * JDK 9+ (configurable through the "java.util.PropertyResourceBundle.encoding" system
+ * property). Note that {@link #loadBundle(Reader)}/{@link #loadBundle(InputStream)}
+ * won't be called in this case either, effectively ignoring overrides in subclasses.
+ * Consider implementing a JDK 9 {@code java.util.spi.ResourceBundleProvider} instead.
+ *
* @author Rod Johnson
* @author Juergen Hoeller
* @see #setBasenames
@@ -80,7 +91,8 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou
* This allows for very efficient hash lookups, significantly faster
* than the ResourceBundle class's own cache.
*/
- private final Map This will be called in case of a {@link #setDefaultEncoding "defaultEncoding"},
+ * including {@link ResourceBundleMessageSource}'s default ISO-8859-1 encoding.
+ * Note that this method can only be called with a {@link ResourceBundle.Control}:
+ * When running on the JDK 9+ module path where such control handles are not
+ * supported, any overrides in custom subclasses will effectively get ignored.
* The default implementation returns a {@link PropertyResourceBundle}.
* @param reader the reader for the target resource
* @return the fully loaded bundle
* @throws IOException in case of I/O failure
* @since 4.2
+ * @see #loadBundle(InputStream)
* @see PropertyResourceBundle#PropertyResourceBundle(Reader)
*/
protected ResourceBundle loadBundle(Reader reader) throws IOException {
return new PropertyResourceBundle(reader);
}
+ /**
+ * Load a property-based resource bundle from the given input stream,
+ * picking up the default properties encoding on JDK 9+.
+ * This will only be called with {@link #setDefaultEncoding "defaultEncoding"}
+ * set to {@code null}, explicitly enforcing the platform default encoding
+ * (which is UTF-8 with a ISO-8859-1 fallback on JDK 9+ but configurable
+ * through the "java.util.PropertyResourceBundle.encoding" system property).
+ * Note that this method can only be called with a {@link ResourceBundle.Control}:
+ * When running on the JDK 9+ module path where such control handles are not
+ * supported, any overrides in custom subclasses will effectively get ignored.
+ * The default implementation returns a {@link PropertyResourceBundle}.
+ * @param inputStream the input stream for the target resource
+ * @return the fully loaded bundle
+ * @throws IOException in case of I/O failure
+ * @since 5.1
+ * @see #loadBundle(Reader)
+ * @see PropertyResourceBundle#PropertyResourceBundle(InputStream)
+ */
+ protected ResourceBundle loadBundle(InputStream inputStream) throws IOException {
+ return new PropertyResourceBundle(inputStream);
+ }
+
/**
* Return a MessageFormat for the given bundle and code,
* fetching already generated MessageFormats from the cache.
@@ -284,7 +336,8 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou
if (msg != null) {
if (codeMap == null) {
codeMap = new ConcurrentHashMap<>();
- Map