Closed Peter-Maeding closed 2 weeks ago
Thanks a lot for the analysis and reporting.
I'm not sure how important this "Control"-thing is for lanterna. Maybe it can just be removed without any replacement.
My fear is that the replacement mentioned is only available for newer Java versions than what are supported by Lanterna.
Do you feel able to create a PR for it - that would still work with e.g. Java8 as well?
Is using named modules essential for your application?
On Wed, Oct 30, 2024 at 9:18 PM Peter Mäding @.***> wrote:
I have a lanterna app that uses modules. After setting a default locale other than English I noticed that the app still shows the english values (e.g. LocalizedString.Cancel.toString() will always return "Cancel"). This works as expected when used in an app without modules.
After some debugging I found that lanterna fails to load its resource bundles in BundleLocator on line 73:
return ResourceBundle.getBundle(bundleName, locale, loader, new UTF8Control());
This code throws java.lang.UnsupportedOperationException: ResourceBundle.Control not supported in named modules
The javadoc of ResourceBundle.Control states the following about this problem:
ResourceBundle.Control is designed for an application deployedin an unnamed module, for example to support resource bundles innon-standard formats or package localized resources in a non-traditional convention. ResourceBundleProvider is the replacement for ResourceBundle.Control when migrating to modules. UnsupportedOperationException will be thrown when a factory method that takes the ResourceBundle.Control parameter is called. [...] ResourceBundle.Control is not supported in named modules. If the ResourceBundle.getBundle method with a ResourceBundle.Control is called in a named module, the method will throw an UnsupportedOperationException. Any service providers of ResourceBundleControlProvider are ignored in named modules.
— Reply to this email directly, view it on GitHub https://github.com/mabe02/lanterna/issues/620, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIDBMR43G54PJJTJURPJPDZ6E5HZAVCNFSM6AAAAABQ45ON6GVHI2DSMVQWIX3LMV43ASLTON2WKOZSGYZDKMRUGQZTANY . You are receiving this because you are subscribed to this thread.Message ID: @.***>
I looked a bit into how java loads resource bundles. It seems property bundles used to be loaded with the ISO-8859-1 charset. If I understand the comments correctly lanterna used the custom Control to use UTF-8 instead. As of java 9 the default encoding for resource bundles is already UTF-8 and can be set to ISO-8859-1 by a system property. So for newer java versions at least the control doesn't seem necessary.
I also took a look at the ResourceBundleProvider thing and unfortunately it was introduced with java 9, so no chance there.
The only simple solution i can think of right now is to only use the Control in java 8 and below. Something along the lines of this:
private ResourceBundle getBundle(Locale locale) {
if (Runtime.version().major() < 9) {
return ResourceBundle.getBundle(bundleName, locale, loader, new UTF8Control());
} else {
return ResourceBundle.getBundle(bundleName, locale, loader);
}
}
That does kinda feel like a hack though. I'll have to think more about a better solution.
Named modules are not essential for my project, I'd just rather use them (it's a personal project after all). For the time beeing I can live with the english defaults in the few places my app relies on lanterna's localization.
Would it be a solution to put the current logic (with Control) into a try-block and retry the same getBundle without Control in the catch-handler for java.lang.UnsupportedOperationException ?
Peter Mäding @.***> schrieb am Di., 5. Nov. 2024, 21:11:
I looked a bit into how java loads resource bundles. It seems property bundles used to be loaded with the ISO-8859-1 charset. If I understand the comments correctly lanterna used the custom Control to use UTF-8 instead. As of java 9 the default encoding for resource bundles is already UTF-8 and can be set to ISO-8859-1 by a system property. So for newer java versions at least the control doesn't seem necessary.
I also took a look at the ResourceBundleProvider thing and unfortunately it was introduced with java 9, so no chance there.
The only simple solution i can think of right now is to only use the Control in java 8 and below. Something along the lines of this:
private ResourceBundle getBundle(Locale locale) { if (Runtime.version().major() < 9) { return ResourceBundle.getBundle(bundleName, locale, loader, new UTF8Control()); } else { return ResourceBundle.getBundle(bundleName, locale, loader); } }
That does kinda feel like a hack though. I'll have to think more about a better solution.
Named modules are not essential for my project, I'd just rather use them (it's a personal project after all). For the time beeing I can live with the english defaults in the few places my app relies on lanterna's localization.
— Reply to this email directly, view it on GitHub https://github.com/mabe02/lanterna/issues/620#issuecomment-2458064044, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIDBMQ34ICZLMZQ5CUU2VLZ7EQ6LAVCNFSM6AAAAABQ45ON6GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJYGA3DIMBUGQ . You are receiving this because you commented.Message ID: @.***>
I honestly have no idea why I didn't think of that. That sounds like the most obvious and simplest solution. I'll try that an make a PR when I find the time.
Thank you!
I have a lanterna app that uses modules. After setting a default locale other than English I noticed that the app still shows the english values (e.g.
LocalizedString.Cancel.toString()
will always return"Cancel"
). This works as expected when used in an app without modules.After some debugging I found that lanterna fails to load its resource bundles in BundleLocator on line 73:
This code throws
java.lang.UnsupportedOperationException: ResourceBundle.Control not supported in named modules
The javadoc of ResourceBundle.Control states the following about this problem: