Linux更新后JVM中的文件编码错误

时间:2014-08-28 12:17:21

标签: java unix encoding locale

更新linux和java(1.6.0.13-> 1.6.0.45)后,Java进程使用不同的文件编码(System Property file.encoding)

新操作系统版本。不幸的是我不再知道以前的版本了。但我可以说,更新出错了。我的Collegue首先使用x32 OS版本进行了更新,然后重新安装了x64版本。

>uname -a
Linux <hostname> 2.6.31.5-0.1-desktop #1 SMP PREEMPT 2009-10-26 15:49:03 +0100 x86_64 x86_64 x86_64 GNU/Linux

区域设置

>locale
LANG=en_US.ISO8859-1
LC_CTYPE=en_US.ISO8859-1
LC_NUMERIC="en_US.ISO8859-1"
LC_TIME="en_US.ISO8859-1"
LC_COLLATE="en_US.ISO8859-1"
LC_MONETARY="en_US.ISO8859-1"
LC_MESSAGES="en_US.ISO8859-1"
LC_PAPER="en_US.ISO8859-1"
LC_NAME="en_US.ISO8859-1"
LC_ADDRESS="en_US.ISO8859-1"
LC_TELEPHONE="en_US.ISO8859-1"
LC_MEASUREMENT="en_US.ISO8859-1"
LC_IDENTIFICATION="en_US.ISO8859-1"
LC_ALL=

测试程序

public class Test
{
  public static void main(String[] args)
  {
    System.out.println(System.getProperty("file.encoding"));
  }
}

如果我启动此测试程序,则返回ANSI_X3.4-1968。在具有相同区域设置的其他计算机上,它将返回ISO8859-1。即使我从显式环境变量开始,它仍然保持不变。唯一可行的解​​决方案是使用-Dfile.encoding选项。但我不想调整所有使用java的脚本(tomcat,maven,ant,hudson ....)。我想恢复旧的行为,即从系统区域设置定义中检索Java程序中的文件编码。

>java Test
ANSI_X3.4-1968

>LANG=de_DE.ISO8859-1 java Test
ANSI_X3.4-1968

>java -Dfile.encoding=ISO8859-1 Test
ISO8859-1

至少c程序获得正确的编码,不使用ANSI_X3.4-1968

>idn --debug  --quiet "a.de"
Charset `ISO-8859-1'.
....

是否有人知道,如果有任何特定于jvm的设置,可能会在操作系统或java更新期间丢失。

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:4)

感谢icza。我用Google搜索了一点JAVA_OPTS,发现我应该使用JAVA_TOOL_OPTIONS代替。 见How do I use the JAVA_OPTS environment variable?

或_JAVA_OPTIONS: Running java with JAVA_OPTS env variable

对于运行时和编译器来说,两者都运行得很好

>export JAVA_TOOL_OPTIONS=-Dfile.encoding=ISO8859-1
>java Test
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=ISO8859-1
ISO8859-1

>javac Test.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=ISO8859-1

>export _JAVA_OPTIONS=-Dfile.encoding=ISO8859-1
>java Test
Picked up _JAVA_OPTIONS: -Dfile.encoding=ISO8859-1
ISO8859-1

>javac Test.java
Picked up _JAVA_OPTIONS: -Dfile.encoding=ISO8859-1

答案 1 :(得分:1)

只是点击类似的东西(在Debian上)。这是由未在/etc/locale.gen中配置的语言环境的默认LANG / LC设置引起的。

要修复,我取消注释/etc/locale.gen中的相应行并运行sudo locale-gen。

我很惊讶Java没有对此发出任何警告。例如,Perl发出巨响,告诉你一些事情已经破裂:

$ LANG=pl_PL.UTF-8 perl -e ''                
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
    LANGUAGE = "en_GB:en",
    LC_ALL = (unset),
    LANG = "pl_PL.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

另外,要解释一些其他行为:ANSI_X3.4-1968只是一种说“ASCII”的官方(有点不透明)方式,而“ISO-8859.1”是“通常的”8位超集ASCII有各种名称,包括“西方”或“拉丁语1”,就DOS或Windows旧版本等操作系统而言,它与“标准”字符集最接近。