
EOS Server在tomcat、jboss、webshphere和weblogic92的开启控制台上,license启动的打印中文信息为"本产品授权:Primeton Evaluation Customer",但在weblogic10上,确显示为乱码,经过认真排查,终于找到理由。
仔细调试,发现weblogic10的log4j和eos使用的log4j-1.2.8.jar有冲突,有一个jar(bea10\modules\com.bea.core.apache.log4j_1.2.13.jar)先于eosdomain/lib/log4j-1.2.8.jar加载,因此乱码应该是两个版本jar差异导致的(weblogic10上用到了1.2.13版本的log4j)。
继续调试,发现log4j 1.2.13的版本和以前的log4j-1.2.8版本在以下的这个类的方式上有变化:
1.2.8的org.apache.log4j.ConsoleAppender类:

public void activateOptions() {
if(target.equals(SYSTEM_OUT)) {
setWriter(new OutputStreamWriter(System.out));
} else {
setWriter(new OutputStreamWriter(System.err));
}
}
在修改writer的之后new OutputStreamWriter(System.out),接着调用java.io.OutputStreamWriter类的以下方式
public OutputStreamWriter(OutputStream out) {
super(out);
try {
se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
然后会调用sun.nio.cs.StreamEncoder类的以下方式:

public static StreamEncoder forOutputStreamWriter(OutputStream out,
Object lock,
String charsetName)
throws UnsupportedEncodingException
{
String csn = charsetName;
if (csn == null)
csn = Converters.getDefaultEncodingName(); //取系统默认的字符集
if (!Converters.isCached(Converters.CHAR_TO_BYTE, csn)) {
try {
if (Charset.isSupported(csn))
return new CharsetSE(out, lock, Charset.forName(csn));
} catch (IllegalCharsetNameException x) { }
}
return new ConverterSE(out, lock, csn);
}
可以看出,ConsoleAppender中的有一个OutputStreamWriter负责输出字符流,其编码使用了平台的缺省编码,在我们中文windows上默认是GBK,而英文windows的控制台默认支持GBK编码的。所以可以恰当输出中文。
再看1.2.13的org.apache.log4j.ConsoleAppender类,该办法的谋求已经改变了:
public void activateOptions() {
if (follow) {
if (target.equals(SYSTEM_ERR)) {
setWriter(createWriter(new SystemErrStream()));
} else {
setWriter(createWriter(new SystemOutStream()));
}
} else {
if (target.equals(SYSTEM_ERR)) {
setWriter(createWriter(System.err));
} else {
setWriter(createWriter(System.out));
}
}
super.activateOptions();
}

这里使用了父类WriterAppender的createWriter()方法,如下:
protected OutputStreamWriter createWriter(OutputStream os) {
OutputStreamWriter retval = null;
String enc = getEncoding();
if(enc != null) {
try {
retval = new OutputStreamWriter(os, enc);
} catch(IOException e) {
LogLog.warn("Error initializing output writer.");
LogLog.warn("Unsupported encoding?");
}
}
if(retval == null) {
retval = new OutputStreamWriter(os);
}
return retval;
}
其中的编码使用了WriterAppender中设定的encoding属性,经过调试,该属性是日志配置文件log4j_eos.xml中EOSCONSOLE中设定的编码,是"utf-8"如下:
<appender class="org.apache.log4j.ConsoleAppender" name="EOSCONSOLE">
<param name="Encoding" value="UTF-8"></param>
<param name="Target" value="System.out"></param>
<param name="Threshold" value="DEBUG"></param>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,nnn} %-5p [%c{1}:%L] %m%n"></param>
</layout>
</appender>

这样ConsoleAppdender中的OutputStreamWriter使用了UTF-8编码weblogic10如何关闭控制台,而不是前面的GBK,而英文windows的控制台不支持UTF-8weblogic10如何关闭控制台,所以输出的为乱码。
解决方案:将日志配置文件log4j_eos.xml中console的编码去掉,这样程序就可以去系统默认的编码,从而取到GBK,正确输出中文。
对控制台这样的输出端,最好的方法是取系统默认的字符集编码,而不是强行指定编码。
总结:1.2.13修改了1.2.8中对log4j日志配置中console的appender中Encoding配置项忽略的bug,不过,我们曾经的日志配置在有bug的log4j版本中出错未表现起来,但新版本中仍看到了。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-144174-1.html
建议中国放开2胎政策
向市场进军