Skip to content

Commit 624656e

Browse files
committed
improve the documentation of our resource bundle handling
1 parent c11dd2e commit 624656e

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/localization/BundleContentSubstitutedLocalizationSupport.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,28 @@
4747
import com.oracle.svm.core.jdk.localization.bundles.StoredBundle;
4848
import com.oracle.svm.core.jdk.localization.compression.GzipBundleCompression;
4949
import com.oracle.svm.core.jdk.localization.compression.utils.BundleSerializationUtils;
50+
import com.oracle.svm.core.jdk.localization.substitutions.modes.SubstituteLoadLookup;
5051
import com.oracle.svm.core.util.UserError;
5152
import com.oracle.svm.core.util.VMError;
5253

5354
import jdk.graal.compiler.debug.GraalError;
5455
import sun.util.resources.OpenListResourceBundle;
5556

57+
/**
58+
* This version of LocalizationSupport stores the content of resource bundles in a map to make the
59+
* (Open)ListResourceBundle.getContents() methods of individual resource bundle subclasses
60+
* unreachable. To do this, we substitute the lookup methods that would call the getContents methods
61+
* and provide the content for resource bundles ourselves. For this to work, we have to extract the
62+
* content of the bundles at build time via {@link BundleSerializationUtils#extractContent}.
63+
* <p>
64+
* We could avoid this dependency by including the getContents() methods of (Open)ListResourceBundle
65+
* subclasses in the image, but these methods are huge, so making them reachable would cause
66+
* regressions in compile time and binary size when multiple locales are requested.
67+
*
68+
* @see BundleSerializationUtils
69+
* @see GzipBundleCompression
70+
* @see SubstituteLoadLookup
71+
*/
5672
public class BundleContentSubstitutedLocalizationSupport extends LocalizationSupport {
5773

5874
@Platforms(Platform.HOSTED_ONLY.class)//

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/localization/compression/utils/BundleSerializationUtils.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.graalvm.nativeimage.Platform;
3535
import org.graalvm.nativeimage.Platforms;
3636

37+
import com.oracle.svm.core.jdk.localization.BundleContentSubstitutedLocalizationSupport;
3738
import com.oracle.svm.core.util.VMError;
3839
import com.oracle.svm.util.ReflectionUtil;
3940

@@ -46,6 +47,11 @@ public class BundleSerializationUtils {
4647
* bundles can be resolved this way, except from the {@link java.text.BreakIterator}. In the
4748
* future, it can be extended with a fallback to user defined bundles by using the handleKeySet
4849
* and handleGetObject methods.
50+
* <p>
51+
* {@link BundleContentSubstitutedLocalizationSupport} depends on the ability the extract the
52+
* contents of resource bundles, and we currently do so via the lookup field. If we failed to
53+
* extract the content, we would get a runtime crash when trying to look up the content from our
54+
* substitutions.
4955
*/
5056
@Platforms(Platform.HOSTED_ONLY.class)
5157
@SuppressWarnings("unchecked")
@@ -63,7 +69,18 @@ public static Map<String, Object> extractContent(ResourceBundle bundle) {
6369
clazz = clazz.getSuperclass();
6470
}
6571
}
66-
throw VMError.shouldNotReachHere("Failed to extract content for " + bundle + " of type " + bundle.getClass());
72+
/*
73+
* The list of tested classes could be collected above, but we only need it in case of an
74+
* unlikely failure, therefore we do not want to pollute the fast path with it.
75+
*/
76+
var testedClasses = new ArrayList<Class<?>>();
77+
for (Class<?> testedClass = bundle.getClass().getSuperclass(); testedClass != null && ResourceBundle.class.isAssignableFrom(testedClass); testedClass = testedClass.getSuperclass()) {
78+
testedClasses.add(testedClass);
79+
}
80+
/* See the method's javadoc for more details. */
81+
throw VMError.shouldNotReachHere("Failed to extract the content for " + bundle + " of type " + bundle.getClass() +
82+
". Did not find the `lookup` field in any of the super classes of " + bundle.getClass() + " " + testedClasses +
83+
". This most likely means that the internal implementation of resource bundles in JDK has changed and is now incompatible with our resource bundle handling.");
6784
}
6885

6986
public record SerializedContent(String text, int[] indices) {

0 commit comments

Comments
 (0)