-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Currently java.lang.Module#isReflectivelyExportedOrOpen simply returns true at image-runtime. This is needed to e.g. make e.g. ResourceBundle lookups at image runtime working. The ResourceBundle lookup code involves:
public ResourceBundle newBundle(String baseName, Locale locale, String format,
ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
/*
* Legacy mechanism to locate resource bundle in unnamed module only
* that is visible to the given loader and accessible to the given caller.
*/
String bundleName = toBundleName(baseName, locale);
ResourceBundle bundle = null;
if (format.equals("java.class")) {
try {
Class<?> c = loader.loadClass(bundleName);
// If the class isn't a ResourceBundle subclass, throw a
// ClassCastException.
if (ResourceBundle.class.isAssignableFrom(c)) {
@SuppressWarnings("unchecked")
Class<ResourceBundle> bundleClass = (Class<ResourceBundle>)c;
Module m = bundleClass.getModule();
// To access a resource bundle in a named module,
// either class-based or properties-based, the resource
// bundle must be opened unconditionally,
// same rule as accessing a resource file.
if (m.isNamed() && !m.isOpen(bundleClass.getPackageName())) {
throw new IllegalAccessException("unnamed module can't load " + // 🗲🗲🗲
bundleClass.getName() + " in " + m.toString());
}
...After #3445 got merged this code can now fail with IllegalAccessException (see 🗲🗲🗲) due to moduleinfo no knowing that m.isOpen(bundleClass.getPackageName()) should be true.
As a temporary workaround substitution:
@SuppressWarnings({"unused", "static-method"})
@Substitute
public boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
return true;
}was added to Target_java_lang_Module_JDK11OrLater.
A proper fix would remove that workaround and instead make sure that m.isOpen(bundleClass.getPackageName()) gives the right answer. The hosted isOpen relationships between modules need to be carried over to module-info at runtime.
A good example that demonstrates if this is working correctly is using ResourceBundle.getBundle("sun.security.util.Resources") at image runtime. The image builder arguments always contains
--add-exports=java.base/sun.security.util=org.graalvm.nativeimage.builder
thus the bundle lookup at image built-time succeeds. But for the bundle lookup to also succeed at image runtime this opening up needs to be translated to the corresponding opening-up at image runtime.