Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/reference-manual/native-image/ReachabilityMetadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,8 @@ To request a bundle from a specific module:
{
"resources": [
{
"bundle": "app.module:module.pkg.Bundle"
"module": "app.module"
"bundle": "your.pkg.Bundle"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,13 @@ protected void parseBundlesObject(Object bundlesObject) {
protected void parseBundle(Object bundle, boolean inResourcesSection) {
EconomicMap<String, Object> resource = asMap(bundle, "Elements of 'bundles' list must be a bundle descriptor object");
String bundleNameAttribute = inResourcesSection ? BUNDLE_KEY : NAME_KEY;
checkAttributes(resource, "bundle descriptor object", Collections.singletonList(bundleNameAttribute), Arrays.asList("locales", "classNames", "condition"));
checkAttributes(resource, "bundle descriptor object", Collections.singletonList(bundleNameAttribute), Arrays.asList(MODULE_KEY, "locales", "classNames", "condition"));
String basename = asString(resource.get(bundleNameAttribute));
TypeResult<C> resolvedConfigurationCondition = conditionResolver.resolveCondition(parseCondition(resource));
if (!resolvedConfigurationCondition.isPresent()) {
return;
}
// TODO GR-67556 - Add full support for MODULE_KEY in ResourceBundle configurations
Object locales = resource.get("locales");
if (locales != null) {
List<Locale> asList = asList(locales, "Attribute 'locales' must be a list of locales")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,23 @@ public void addClassBasedResourceBundle(UnresolvedConfigurationCondition conditi

public static final class BundleConfiguration {
public final UnresolvedConfigurationCondition condition;
public final String module;
public final String baseName;
public final Set<String> locales = ConcurrentHashMap.newKeySet();
public final Set<String> classNames = ConcurrentHashMap.newKeySet();

public BundleConfiguration(UnresolvedConfigurationCondition condition, String baseName) {
public BundleConfiguration(UnresolvedConfigurationCondition condition, String module, String baseName) {
this.condition = condition;
this.module = module;
this.baseName = baseName;
}

public BundleConfiguration(UnresolvedConfigurationCondition condition, String baseName) {
this(condition, null, baseName);
}

private BundleConfiguration(BundleConfiguration other) {
this(other.condition, other.baseName);
this(other.condition, other.module, other.baseName);
locales.addAll(other.locales);
classNames.addAll(other.classNames);
}
Expand Down Expand Up @@ -389,6 +395,9 @@ public ConfigurationParser createParser(boolean combinedFileSchema, EnumSet<Conf
public static void printResourceBundle(BundleConfiguration config, JsonWriter writer, boolean combinedFile) throws IOException {
writer.appendObjectStart();
ConfigurationConditionPrintable.printConditionAttribute(config.condition, writer, combinedFile);
if (config.module != null) {
writer.quote("module").appendFieldSeparator().quote(config.module).appendSeparator();
}
writer.quote(combinedFile ? BUNDLE_KEY : NAME_KEY).appendFieldSeparator().quote(config.baseName);
if (!combinedFile && !config.locales.isEmpty()) {
writer.appendSeparator().quote("locales").appendFieldSeparator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
package com.oracle.svm.core.jdk.localization.substitutions;

import java.util.Locale;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Supplier;
Expand Down Expand Up @@ -115,7 +117,7 @@ private static ResourceBundle getBundleImpl(String baseName,
// get resource bundles for a named module only if loader is the module's class loader
if (callerModule.isNamed() && loader == getLoader(callerModule)) {
if (!ImageSingletons.lookup(LocalizationSupport.class).isRegisteredBundleLookup(baseName, locale, control)) {
MissingResourceRegistrationUtils.reportResourceBundleAccess(baseName);
MissingResourceRegistrationUtils.reportResourceBundleAccess(callerModule, baseName);
}
return MissingRegistrationUtils.runIgnoringMissingRegistrations(new Supplier<ResourceBundle>() {
@Override
Expand All @@ -134,7 +136,7 @@ public ResourceBundle get() {
: BootLoader.getUnnamedModule();

if (!ImageSingletons.lookup(LocalizationSupport.class).isRegisteredBundleLookup(baseName, locale, control)) {
MissingResourceRegistrationUtils.reportResourceBundleAccess(baseName);
MissingResourceRegistrationUtils.reportResourceBundleAccess(unnamedModule, baseName);
}
return MissingRegistrationUtils.runIgnoringMissingRegistrations(new Supplier<ResourceBundle>() {
@Override
Expand All @@ -144,6 +146,24 @@ public ResourceBundle get() {
});
}

@Substitute
private static ResourceBundle getBundleFromModule(Class<?> caller,
Module module,
String baseName,
Locale locale,
Control control) {
Objects.requireNonNull(module);
Module callerModule = getCallerModule(caller);
/*
* TODO GR-67556 - Implement proper module-aware LocalizationSupport bundle registration to
* ensure we show MissingResourceRegistrationError in all relevant situations.
*/
if (!ImageSingletons.lookup(LocalizationSupport.class).isRegisteredBundleLookup(baseName, locale, control)) {
MissingResourceRegistrationUtils.reportResourceBundleAccess(module, baseName);
}
return MissingRegistrationUtils.runIgnoringMissingRegistrations(() -> getBundleImpl(callerModule, module, baseName, locale, control));
}

@Alias
private static native Module getCallerModule(Class<?> caller);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.nio.file.Files;
import java.nio.file.spi.FileSystemProvider;
import java.util.Map;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.Set;

Expand Down Expand Up @@ -61,16 +62,18 @@ public static void reportResourceAccess(Module module, String resourcePath) {
report(exception);
}

public static void reportResourceBundleAccess(String baseName) {
var bundleConfig = new ResourceConfiguration.BundleConfiguration(UnresolvedConfigurationCondition.alwaysTrue(), baseName);
public static void reportResourceBundleAccess(Module module, String baseName) {
Objects.requireNonNull(module);
var bundleConfig = new ResourceConfiguration.BundleConfiguration(UnresolvedConfigurationCondition.alwaysTrue(), module.getName(), baseName);
StringWriter json = new StringWriter();
try {
ResourceConfiguration.printResourceBundle(bundleConfig, getJSONWriter(json), true);
} catch (IOException e) {
throw VMError.shouldNotReachHere("In memory JSON printing should not fail");
}
String moduleMessage = module.isNamed() ? " from module " + quote(module.getName()) : "";
MissingResourceRegistrationError exception = new MissingResourceRegistrationError(
resourceError("resource bundle with name " + quote(baseName), json.toString(), "resource-bundles"),
resourceError("resource bundle" + moduleMessage + " with name " + quote(baseName), json.toString(), "resource-bundles"),
baseName);
report(exception);
}
Expand Down
Loading