繁体   English   中英

Java 程序在 jpackage 时使用了错误的语言环境

[英]Java program uses wrong locale when jpackaged

我正在解析表示德式数字的字符串(即,十进制逗号和用于分组数千的可选句号),例如“2.804,13”; 这只是根据我想要的Locale使用DecimalFormat完成的:

package loc_test;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

public class ParseNumbers {
    static final DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.GERMANY);

    public static void main(String[] args) throws Exception {
        for (String s : new String[] { "2.815,53", "2815,53" }) {
            System.out.println(String.format("%s \t-> %s", s, df.parse(s)));
        }
    }
}

这给出了所需的 output,例如,当从命令行编译和运行时:

2.815,53        -> 2815.53
2815,53         -> 2815.53

但是,当我将它捆绑为 jpackage 映像(使用 Gradle 和Badass Runtime Plugin./gradlew jpackageImage )并运行生成的二进制文件时,output 似乎表明使用了错误的语言环境:

2.815,53    -> 2.815
2815,53     -> 281553

我已经尝试了一些东西(徒劳),问题似乎并不在于代码本身:

  1. main中添加了Locale.setDefault(Locale.GERMANY) Locale.getDefault()将显示德语语言环境,但没有效果。
  2. 通过 Java 命令行参数显式设置-Duser.country=DE-Duser.language=de System.getProperty(...)显示预期值,但同样没有效果。 (此外,从命令行,它也可以将这些设置为系统默认值。)
  3. -Djava.locale.providers=COMPAT,CLDR,SPI添加到 jpackage Java 命令行参数(来自此线程)。 同样,我可以从main验证属性设置是否正确,但这没有区别。 (无论如何,早期的 Java 版本似乎一直存在问题。)

我首先使用Java 16 和 Gradle 7.2看到了这个问题; 并且在更新到Java 17 和 Gradle 7.3后它仍然存在。 该问题出现在英语 Linux 系统和德语 Windows 机器上。

--infojpackageImage命令一起使用,Gradle 会告诉我它正在使用哪个 JDK:

Starting process 'command '.../.gradle/jdks/jdk-17+35/bin/jpackage''. Working directory: .../LocTest/app Command: .../.gradle/jdks/jdk-17+35/bin/jpackage --type app-image --input .../LocTest/app/build/install/app/lib --main-jar app.jar --main-class LocTest.App --dest .../LocTest/app/build/jpackage --name app --runtime-image .../LocTest/app/build/jre --java-options -Duser.country=DE --java-options -Duser.language=de --java-options -Djava.locale.providers=COMPAT,CLDR,SPI

当我使用.gradle/jdks/jdk-17+35/bin/java运行 class 时,即运行:

~/.gradle/jdks/jdk-17+35/bin/java -cp app/build/classes/java/main loc_test.App`

这样,问题就不会发生; 数字是正确的。

但是,当我使用与 jpackage 映像捆绑在一起的(假定相同的)JRE 时,确实会出现问题,即,我使用以下方法得到错误的数字:

./app/build/jpackage/app/lib/runtime/bin/java -cp app/build/classes/java/main/ loc_test.App

为什么java打包时会忽略语言环境? 我在这里遗漏了什么,或者这可能是 jpackage 或插件中的错误,或者 Java 版本本身中的错误?

整个 Gradle 示例项目(非常小)可以在 Github 找到

检查运行时映像中包含哪些模块。

例如,当我在 JDK 17 上运行java --list-modules时,我注意到这个模块:

jdk.localedata

我不知道这是否需要它,但我敢打赌,除非特别要求,否则 jpackage 不会包含该模块。

运行./app/build/jpackage/app/lib/runtime/bin/java --list-modules并与~/.gradle/jdks/jdk-17+35/bin/java --list-modules进行比较以确认。 然后考虑使用包含jlinkjdk.localedata制作一个图像,如果它缺少测试这个假设。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM