Hello Vincent Gao, I saw your Java Bugs submission. Unfortunately your stacktrace caused some confusion to our triage because it is an internal exception and that trace is never printed anywhere. Your suggestion is a reasonable enhancement, that we should not use ad-hoc exceptions for control flow, given they need to fill stack traces, which is extremely costly. Since this is a cleanup, we might commit this to mainline JDK first. If this proves to be a performance bottleneck on 25 updates, we can backport. Since you are writing here, I assume this has a non-negligible impact on performance. If you can share a flame graph showing the regression from this exception, or a benchmark difference between 21 and 25.0.1, this would be extremely helpful.
Regards, Chen Liang ________________________________ From: core-libs-dev <[email protected]> on behalf of weigao <[email protected]> Sent: Wednesday, December 10, 2025 9:31 PM To: [email protected] <[email protected]> Subject: Re: [External] Feedback JDK-8318761 : Potential Issue in JDK 25 MessageFormat: Use of Internal Exception for Control Flow hi , because of ``private static FormatStyle fromString(String text)` throw exception and the try catch exception just set the deault value `FormatStyle.SUBFORMATPATTERN` , so why just make this function retuen this value like ? Is it better , right ? ``` private static FormatStyle fromString(String text) { for (FormatStyle style : values()) { // Also check trimmed case-insensitive for historical reasons if (style != FormatStyle.SUBFORMATPATTERN && text.trim().compareToIgnoreCase(style.text) == 0) { return style; } } return FormatStyle.SUBFORMATPATTERN; } ``` weigao <[email protected]<mailto:[email protected]>> 于2025年12月11日周四 11:21写道: Hello, I would like to report a potential design issue in the JDK 25 implementation of MessageFormat. While working with java.util.Locale#getDisplayName(), I found that JDK internals throw and catch an IllegalArgumentException due to the following pattern added in the resource bundles: * sun.util.resources.cldr.LocaleNames * sun.util.resources.LocaleNames The pattern in question is: DisplayNamePattern: {0,choice,0#|1#{1}|2#{1} ({2})} This change originates from the following commit: adoptium/jdk@00ffc42 ― which adds a pattern for MessageFormat. However, choice is not a valid type for FormatStyle. As a result, calling Locale#getDisplayName() triggers the following exception inside JDK code: java.lang.IllegalArgumentException at java.base/java.text.MessageFormat$FormatStyle.fromString(MessageFormat.java:2013) at java.base/java.text.MessageFormat.formatFromPattern(MessageFormat.java:1718) at java.base/java.text.MessageFormat.setFormatFromPattern(MessageFormat.java:1679) at java.base/java.text.MessageFormat.applyPatternImpl(MessageFormat.java:660) at java.base/java.text.MessageFormat.<init>(MessageFormat.java:516) at java.base/java.util.Locale.getDisplayName(Locale.java:2309) The implementation currently relies on exception-based logic: try { fStyle = FormatStyle.fromString(style); } catch (IllegalArgumentException iae) { fStyle = FormatStyle.SUBFORMATPATTERN; } I understand that MessageFormat catches this exception and falls back to SUBFORMATPATTERN, but using exceptions to control expected logic paths may not be ideal―especially since FormatStyle.fromString() is only used by MessageFormat. A potentially cleaner approach could be to have FormatStyle.fromString() return FormatStyle.SUBFORMATPATTERN directly when encountering unknown style identifiers, instead of throwing an exception. JDK Version Observed: OpenJDK Runtime Environment Temurin-25.0.1+8 (build 25.0.1+8-LTS) Please let me know if this behavior is intentional, or if it should be considered for improvement. Best regards, vincent gao
