Skip to content

fix i18n loading from uberjar - #8909

Merged
NoahTheDuke merged 1 commit into
mtgred:masterfrom
xdg-forks:fix-i18n-uberjar
Nov 2, 2026
Merged

NoahTheDuke merged 1 commit into
mtgred:masterfrom
xdg-forks:fix-i18n-uberjar

Conversation

@xdg

@xdg xdg commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

The uberjar exits at startup. The :web/i18n init calls
(io/file (io/resource "public/i18n")), which throws "Not a file:
jar:file:..." when the resource is inside a jar. web.system/start
swallows the exception, so the process exits 0 with no log. Running
from source still works because resources/ is a directory on the
classpath.

This regressed in #8748 (5e9cf86), which moved the ftl files into
per-language directories and replaced the jar-safe loader from #8166
(49c33f1).

Look up /ui.ftl and /messages.ftl with io/resource
instead:

  • Only those two files load. io/resource can't list a directory
    inside a jar, so a new file has to be added to the list.
  • They are joined ui first, then messages. Before, they were joined in
    file-seq order. No message ID appears in both files, so the result
    is the same.
  • The when-let directory check is dropped rather than changed to
    (when (io/resource dir) ...). Inside a jar, a directory resolves
    only if the jar has an explicit entry for it, so the check could
    skip every translation silently. A missing directory now returns []
    instead of nil, and every caller either ignores the result or
    checks empty?.

Most of the diff is reindentation from dropping the when-let. It's
easier to read with whitespace changes hidden.

Tested: jinteki.i18n-test passes. Loading from a jar containing
public/i18n gives the same 11 languages as loading from source. A
Docker image built from this branch runs on my deployment.

AI assistance was used.

The uberjar exits at startup. The :web/i18n init calls
(io/file (io/resource "public/i18n")), which throws "Not a file:
jar:file:..." when the resource is inside a jar. web.system/start
swallows the exception, so the process exits 0 with no log. Running
from source still works because resources/ is a directory on the
classpath.

This regressed in 5e9cf86, which moved the ftl files into
per-language directories and replaced the jar-safe loader from
49c33f1.

Look up <lang>/ui.ftl and <lang>/messages.ftl with io/resource
instead:

- Only those two files load. io/resource can't list a directory
  inside a jar, so a new file has to be added to the list.
- They are joined ui first, then messages. Before, they were joined in
  file-seq order. No message ID appears in both files, so the result
  is the same.
- The when-let directory check is dropped rather than changed to
  (when (io/resource dir) ...). Inside a jar, a directory resolves
  only if the jar has an explicit entry for it, so the check could
  skip every translation silently. A missing directory now returns []
  instead of nil, and every caller either ignores the result or
  checks empty?.
@xdg xdg mentioned this pull request Nov 2, 2026
@NoahTheDuke

Copy link
Copy Markdown
Collaborator

oh crap good catch. annoying that i keep missing this.

@NoahTheDuke
NoahTheDuke merged commit 9014545 into mtgred:master Nov 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants