Outerstellar Outerstellar
← Back to blog

Catch Missing Translations at Build Time with Kotlin

· Alexander Brandt · 2m read

Catch Missing Translations at Build Time with Kotlin

Missing translations in production are embarrassing and avoidable. The Outerstellar Framework includes a Maven plugin that validates ResourceBundle translations during mvn verify — catch missing keys, unused translations, and parameter mismatches before they ship.

The problem

Standard Java/Kotlin ResourceBundle fails silently. If messages_de.properties is missing a key that messages_en.properties has, you get a fallback to English at best, or a MissingResourceException at worst. You won't know until a German-speaking user reports it.

Common translation bugs:

BugExampleWhen you find it
Missing keywelcome.subtitle exists in en but not deProduction
Unused keyold.feature.title defined but never referenced in codeNever (dead code)
Undefined referenceCode calls i18n.translate("new.feature") but no bundle has itRuntime crash
Parameter mismatchen has Hello {0}, you have {1} items but de has Hallo {0} (missing {1})Production, subtly

The solution

Add the validator plugin to your build:

<plugin>
    <groupId>io.github.rygel</groupId>
    <artifactId>outerstellar-i18n-validator-maven-plugin</artifactId>
    <version>1.0.14</version>
    <executions>
        <execution>
            <goals><goal>validate</goal></goals>
            <configuration>
                <bundleName>messages</bundleName>
                <sourceDirectories>
                    <directory>src/main/kotlin</directory>
                </sourceDirectories>
                <locales>
                    <locale>en</locale>
                    <locale>de</locale>
                    <locale>fr</locale>
                </locales>
            </configuration>
        </execution>
    </executions>
</plugin>

Now mvn verify checks all four categories of translation issues and fails the build if any are found.

What gets checked

Missing translations

Keys present in the default bundle but absent in a locale:

ERROR: Key 'welcome.subtitle' is missing in locale 'de'

Unused keys

Keys defined in bundles but never referenced in source code:

WARN: Key 'old.feature.title' is defined but not referenced in source

Undefined references

Keys used in source code but missing from all bundles:

ERROR: Key 'new.feature.description' is referenced in code but not defined in any bundle

Parameter mismatches

Placeholder differences between locales:

ERROR: Key 'item.count' has parameters {0}, {1} in 'en' but only {0} in 'de'

CLI alternative

For CI pipelines or projects not using Maven:

java -jar outerstellar-i18n-validator-cli.jar \
    --bundle messages \
    --source src/main/kotlin \
    --locales en,de,fr

The i18n service

The Outerstellar Framework also provides a translation service that wraps ResourceBundle with:

  • Parameter substitution ({0}, {1} style)
  • Locale fallback chains
  • Thread-safe cached lookups
  • Hot reload at runtime (dev mode)
val i18n = I18nService.create("messages")
val greeting = i18n.translate("welcome.message", userName)
val german = i18n.translate("welcome.title", Locale.GERMAN)

FAQ

How do I validate Kotlin translations at build time?

Add the outerstellar-i18n-validator-maven-plugin to your pom.xml. It runs during mvn verify and checks for missing keys, unused keys, undefined references, and parameter mismatches between locales. It fails the build if issues are found.

What translation problems can be caught at build time?

Four categories: missing translations (keys in the default bundle absent in a locale), unused keys (defined but never referenced in code), undefined references (used in code but missing from all bundles), and parameter mismatches (placeholder differences like {0}, {1} between locales).