Skip to content

Commit 52594f5

Browse files
committed
[GR-66737] Fix MissingResourceRegistration behaviour for resource bundle access via module.
PullRequest: graal/21421
2 parents c5d886e + ebd0112 commit 52594f5

File tree

5 files changed

+43
-9
lines changed

5 files changed

+43
-9
lines changed

docs/reference-manual/native-image/ReachabilityMetadata.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,8 @@ To request a bundle from a specific module:
612612
{
613613
"resources": [
614614
{
615-
"bundle": "app.module:module.pkg.Bundle"
615+
"module": "app.module"
616+
"bundle": "your.pkg.Bundle"
616617
}
617618
]
618619
}

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ResourceConfigurationParser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,13 @@ protected void parseBundlesObject(Object bundlesObject) {
7171
protected void parseBundle(Object bundle, boolean inResourcesSection) {
7272
EconomicMap<String, Object> resource = asMap(bundle, "Elements of 'bundles' list must be a bundle descriptor object");
7373
String bundleNameAttribute = inResourcesSection ? BUNDLE_KEY : NAME_KEY;
74-
checkAttributes(resource, "bundle descriptor object", Collections.singletonList(bundleNameAttribute), Arrays.asList("locales", "classNames", "condition"));
74+
checkAttributes(resource, "bundle descriptor object", Collections.singletonList(bundleNameAttribute), Arrays.asList(MODULE_KEY, "locales", "classNames", "condition"));
7575
String basename = asString(resource.get(bundleNameAttribute));
7676
TypeResult<C> resolvedConfigurationCondition = conditionResolver.resolveCondition(parseCondition(resource));
7777
if (!resolvedConfigurationCondition.isPresent()) {
7878
return;
7979
}
80+
// TODO GR-67556 - Add full support for MODULE_KEY in ResourceBundle configurations
8081
Object locales = resource.get("locales");
8182
if (locales != null) {
8283
List<Locale> asList = asList(locales, "Attribute 'locales' must be a list of locales")

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,23 @@ public void addClassBasedResourceBundle(UnresolvedConfigurationCondition conditi
116116

117117
public static final class BundleConfiguration {
118118
public final UnresolvedConfigurationCondition condition;
119+
public final String module;
119120
public final String baseName;
120121
public final Set<String> locales = ConcurrentHashMap.newKeySet();
121122
public final Set<String> classNames = ConcurrentHashMap.newKeySet();
122123

123-
public BundleConfiguration(UnresolvedConfigurationCondition condition, String baseName) {
124+
public BundleConfiguration(UnresolvedConfigurationCondition condition, String module, String baseName) {
124125
this.condition = condition;
126+
this.module = module;
125127
this.baseName = baseName;
126128
}
127129

130+
public BundleConfiguration(UnresolvedConfigurationCondition condition, String baseName) {
131+
this(condition, null, baseName);
132+
}
133+
128134
private BundleConfiguration(BundleConfiguration other) {
129-
this(other.condition, other.baseName);
135+
this(other.condition, other.module, other.baseName);
130136
locales.addAll(other.locales);
131137
classNames.addAll(other.classNames);
132138
}
@@ -389,6 +395,9 @@ public ConfigurationParser createParser(boolean combinedFileSchema, EnumSet<Conf
389395
public static void printResourceBundle(BundleConfiguration config, JsonWriter writer, boolean combinedFile) throws IOException {
390396
writer.appendObjectStart();
391397
ConfigurationConditionPrintable.printConditionAttribute(config.condition, writer, combinedFile);
398+
if (config.module != null) {
399+
writer.quote("module").appendFieldSeparator().quote(config.module).appendSeparator();
400+
}
392401
writer.quote(combinedFile ? BUNDLE_KEY : NAME_KEY).appendFieldSeparator().quote(config.baseName);
393402
if (!combinedFile && !config.locales.isEmpty()) {
394403
writer.appendSeparator().quote("locales").appendFieldSeparator();

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/localization/substitutions/Target_java_util_ResourceBundle.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
package com.oracle.svm.core.jdk.localization.substitutions;
2626

2727
import java.util.Locale;
28+
import java.util.Objects;
2829
import java.util.ResourceBundle;
30+
import java.util.ResourceBundle.Control;
2931
import java.util.concurrent.ConcurrentHashMap;
3032
import java.util.concurrent.ConcurrentMap;
3133
import java.util.function.Supplier;
@@ -115,7 +117,7 @@ private static ResourceBundle getBundleImpl(String baseName,
115117
// get resource bundles for a named module only if loader is the module's class loader
116118
if (callerModule.isNamed() && loader == getLoader(callerModule)) {
117119
if (!ImageSingletons.lookup(LocalizationSupport.class).isRegisteredBundleLookup(baseName, locale, control)) {
118-
MissingResourceRegistrationUtils.reportResourceBundleAccess(baseName);
120+
MissingResourceRegistrationUtils.reportResourceBundleAccess(callerModule, baseName);
119121
}
120122
return MissingRegistrationUtils.runIgnoringMissingRegistrations(new Supplier<ResourceBundle>() {
121123
@Override
@@ -134,7 +136,7 @@ public ResourceBundle get() {
134136
: BootLoader.getUnnamedModule();
135137

136138
if (!ImageSingletons.lookup(LocalizationSupport.class).isRegisteredBundleLookup(baseName, locale, control)) {
137-
MissingResourceRegistrationUtils.reportResourceBundleAccess(baseName);
139+
MissingResourceRegistrationUtils.reportResourceBundleAccess(unnamedModule, baseName);
138140
}
139141
return MissingRegistrationUtils.runIgnoringMissingRegistrations(new Supplier<ResourceBundle>() {
140142
@Override
@@ -144,6 +146,24 @@ public ResourceBundle get() {
144146
});
145147
}
146148

149+
@Substitute
150+
private static ResourceBundle getBundleFromModule(Class<?> caller,
151+
Module module,
152+
String baseName,
153+
Locale locale,
154+
Control control) {
155+
Objects.requireNonNull(module);
156+
Module callerModule = getCallerModule(caller);
157+
/*
158+
* TODO GR-67556 - Implement proper module-aware LocalizationSupport bundle registration to
159+
* ensure we show MissingResourceRegistrationError in all relevant situations.
160+
*/
161+
if (!ImageSingletons.lookup(LocalizationSupport.class).isRegisteredBundleLookup(baseName, locale, control)) {
162+
MissingResourceRegistrationUtils.reportResourceBundleAccess(module, baseName);
163+
}
164+
return MissingRegistrationUtils.runIgnoringMissingRegistrations(() -> getBundleImpl(callerModule, module, baseName, locale, control));
165+
}
166+
147167
@Alias
148168
private static native Module getCallerModule(Class<?> caller);
149169

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/resources/MissingResourceRegistrationUtils.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.nio.file.Files;
3030
import java.nio.file.spi.FileSystemProvider;
3131
import java.util.Map;
32+
import java.util.Objects;
3233
import java.util.ResourceBundle;
3334
import java.util.Set;
3435

@@ -61,16 +62,18 @@ public static void reportResourceAccess(Module module, String resourcePath) {
6162
report(exception);
6263
}
6364

64-
public static void reportResourceBundleAccess(String baseName) {
65-
var bundleConfig = new ResourceConfiguration.BundleConfiguration(UnresolvedConfigurationCondition.alwaysTrue(), baseName);
65+
public static void reportResourceBundleAccess(Module module, String baseName) {
66+
Objects.requireNonNull(module);
67+
var bundleConfig = new ResourceConfiguration.BundleConfiguration(UnresolvedConfigurationCondition.alwaysTrue(), module.getName(), baseName);
6668
StringWriter json = new StringWriter();
6769
try {
6870
ResourceConfiguration.printResourceBundle(bundleConfig, getJSONWriter(json), true);
6971
} catch (IOException e) {
7072
throw VMError.shouldNotReachHere("In memory JSON printing should not fail");
7173
}
74+
String moduleMessage = module.isNamed() ? " from module " + quote(module.getName()) : "";
7275
MissingResourceRegistrationError exception = new MissingResourceRegistrationError(
73-
resourceError("resource bundle with name " + quote(baseName), json.toString(), "resource-bundles"),
76+
resourceError("resource bundle" + moduleMessage + " with name " + quote(baseName), json.toString(), "resource-bundles"),
7477
baseName);
7578
report(exception);
7679
}

0 commit comments

Comments
 (0)