提问者:小点点

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


更新linux和java(1.6.0.13后-

新OS版本。不幸的是,我不知道以前的版本了。但是我可以告诉你,更新出错了。我的同事首先使用x32OS版本进行更新,然后我们重新安装了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.编码选项。但是我不想调整所有使用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。

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

有没有人知道,如果有任何jvm特定的设置,在OS或java更新期间可能会丢失。

感谢任何帮助。


共2个答案

匿名用户

感谢icza.我用google搜索了一下JAVA_OPTS,发现,我应该用JAVA_TOOL_OPTIONS代替.见如何使用JAVA_OPTS环境变量?

或_JAVA_OPTIONS:使用JAVA_OPTSenv变量运行java

对于运行时和编译器,两者都可以正常工作

>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

匿名用户

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

为了解决这个问题,我从 /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是ASCII的“通常”8位超集,有各种名称,包括“西方”或“拉丁1”,就操作系统(如DOS或旧版本的Windows)而言,它是最接近“标准”字符集的东西。