Opened 2 hours ago
Last modified 106 minutes ago
#24940 new enhancement
[PATCH] Fall back to a UTF-8 locale on Linux, and explain unmappable file names instead of asking for a bug report
| Reported by: | wangi | Owned by: | team |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | Core | Version: | |
| Keywords: | linux locale encoding InvalidPathException flatpak template_report | Cc: |
Description
This follows up #14596, which is closed as invalid but still collects duplicates: more than 30 so far, and it was updated again this week. All of them are java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters, thrown by the file chooser when a folder holds a file with a non-ASCII name.
What steps will reproduce the problem?
- On Linux, start JOSM with a UTF-8 locale which is not installed, e.g.
LANG=fr_FR.UTF-8on a system that has onlyen_US.UTF-8— which is what happens inside a Flatpak sandbox — or withLANG=C. - File > Open, and go to a folder which holds a file called
Capture d'écran.png.
What is the expected result?
The folder is listed.
What happens instead?
InvalidPathException, and JOSM asks for a bug report.
Please provide any additional information below. Attach a screenshot if possible.
The reasoning in #14596 is that the user chose LANG=C. That doesn't match most of the duplicates: since the status report gained the encodings (#14596 comment:41), many show LANG=en_GB.UTF-8 next to sun.jnu.encoding=ANSI_X3.4-1968. That is a UTF-8 locale which is not installed: glibc falls back to C, and Java then decodes every file name as ASCII. Measured with OpenJDK 25:
| Environment | sun.jnu.encoding | non-ASCII file name |
|---|---|---|
LANG=en_GB.UTF-8 (installed) | UTF-8 | OK |
LANG=C | ANSI_X3.4-1968 | InvalidPathException
|
LANG=fr_FR.UTF-8 (not installed) | ANSI_X3.4-1968 | InvalidPathException
|
LANG=C -Dsun.jnu.encoding=UTF-8 | ANSI_X3.4-1968 | InvalidPathException
|
LANG=C -Dfile.encoding=UTF-8 | ANSI_X3.4-1968 | InvalidPathException
|
LANG=C.UTF-8 | UTF-8 | OK |
LANG=fr_FR.UTF-8 LC_CTYPE=C.UTF-8 | ANSI_X3.4-1968 | InvalidPathException
|
LANG=fr_FR.UTF-8 LC_ALL=C.UTF-8 | UTF-8 | OK |
So JOSM cannot fix this once Java is running: sun.jnu.encoding is fixed at startup, and setting it with -D is ignored (the suggestion in #14596 comment:40 does not work); file.encoding is not used for file names at all. It has to be fixed in the environment before Java starts — which, as #14596 comment:74 says, depends on the installer. Note also the second-to-last row: setting only LC_CTYPE is not enough, because setlocale(LC_ALL, "") fails as a whole when any category names a locale which is not installed.
The attached patches are independent of each other.
utf8-file-names-launcher.patch — the installer part. The Linux launchers native/linux/{tested,latest}/usr/bin/josm* set LC_ALL=C.UTF-8 when the locale cannot be set or is ASCII, provided C.UTF-8 is available (it is built into glibc 2.35 and later):
if { [ -n "$(locale 2>&1 >/dev/null)" ] || [ "$(locale charmap 2>/dev/null)" = "ANSI_X3.4-1968" ]; } \ && [ -z "$(LC_ALL=C.UTF-8 locale 2>&1 >/dev/null)" ]; then export LC_ALL=C.UTF-8 fi
- This reaches Flatpak users as well: the Flathub package runs this script (its only patch adds HiDPI scaling).
- It does not change the language of JOSM. When the locale cannot be set, Java already falls back to English.
- Locales which work are left alone, including non-UTF-8 ones such as ISO-8859-1, where
sun.jnu.encodingis legitimately not UTF-8. Iflocaleis missing, orC.UTF-8is not available, the check does nothing. - Tested by running both scripts, with a stand-in for
javathat lists such a folder, underLANG=C, a missingLANG, a missingLANGwith a validLC_CTYPE, and a working locale. All four list the folder; the unmodified script fails with the missingLANG.shellcheck0.11.0 reports nothing new: its only finding, SC1091 about the sourced/etc/default/josm, is the same on the unmodified scripts. - One thing I could not check: whether
/usr/bin/localeis present in the Freedesktop runtime. If it is not, the check does nothing there.
utf8-file-names-dialog.patch — for the ways of starting JOSM whose launcher JOSM does not control: Snap (#22887), Java Web Start and plain java -jar. A JNLP file can set system properties but not environment variables, so Web Start cannot be fixed from josm.jnlp. New ReportedException.isUnmappableFileName() recognises such an InvalidPathException in the cause chain while sun.jnu.encoding is not UTF-8, and BugReportDialog.showFor() then explains the problem instead of asking for a bug report, as it already does for an OutOfMemoryError:
JOSM cannot handle the name of a file, because it is running with the character set ANSI_X3.4-1968 for file names, which cannot represent it. This happens when JOSM is started without a UTF-8 locale, for example with LANG=C, or with a locale which is not installed. Please start JOSM with the environment variable LC_ALL=C.UTF-8.
It is shown once per session, since browsing another folder throws the same exception again. Requiring sun.jnu.encoding not to be UTF-8 keeps it from blaming the locale when it is not at fault, e.g. for a file name in ISO-8859-1 on a UTF-8 system.
Unit tests: ReportedExceptionTest.testIsUnmappableFileName() covers the exception on its own and as a cause, another InvalidPathException, an unrelated exception, and a UTF-8 file name encoding. New BugReportDialogTest checks that the message is shown, exactly once, and that no bug report dialog is opened. Both fail without the patch. All tests in org.openstreetmap.josm.tools.bugreport and org.openstreetmap.josm.gui.bugreport pass, and checkstyle and PMD report nothing for the changed files. Both patches are against r19636.
Attachments (2)
Change History (3)
by , 2 hours ago
| Attachment: | utf8-file-names-launcher.patch added |
|---|
by , 2 hours ago
| Attachment: | utf8-file-names-dialog.patch added |
|---|



Also suggested the shell script change on the snap #22887 ticket.