Maison > Questions et réponses > le corps du texte
package test;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class TstCall {
public static void main(String[] args) throws ServiceException, RemoteException {
//初始化参数
String chgKind = "1"; // 1:增加;2:变更
String workNo = "CY_yy" ;
String workNAme = "白莉";
String mobile = "15133333333";
String dealerId = "920301832";
String chgDate = "20160302";
String YGZurl = null ;
//创建服务
Service YGZservice = new Service();
//创建调用句柄
Call YGZcall = (Call) YGZservice.createCall();
//设置请求地址
YGZcall.setTargetEndpointAddress(YGZurl);
YGZcall.setOperationName(new QName(null, "IfService"));
try
{
Object o =YGZcall.invoke(new Object[] { "","123","Service","",
"<request><userlist><user><systemtype note=\"sour\">1</systemtype><kind note=\"chg\">"+chgKind+"</kind>"
+"<id note=\"num\">"+workNo+"</id><name note=\"numname\">"+workNAme+"</name><limit note=\"pp\">1</limit>"
+"<tel note=\"tel\">"+mobile+"</tel><belongfkid note=\"dealerID\">"+dealerId+"</belongfkid><starttime note=\"chgtime\">"+chgDate+"</starttime>"
+"</user></userlist></request>" });
}catch(Exception e) {
e.printStackTrace();
}
}
}
在window下执行都正常,但是在linux下执行报错:
执行语句:
java -jar -Djava.ext.dirs=/home/oracle/xf_everyday_check_p/javajar/lib/ test.jar
报错日志:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope...}Server.userException
faultSubcode:
faultString: java.lang.NullPointerException
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.lang.NullPointerException
at java.security.SecureRandom.nextBytes(SecureRandom.java:292)
at org.apache.axis.utils.SessionUtils.generateSessionId(SessionUtils.java:62)
at org.apache.axis.SOAPPart.<init>(SOAPPart.java:164)
at org.apache.axis.Message.setup(Message.java:377)
at org.apache.axis.Message.<init>(Message.java:246)
at org.apache.axis.client.Call.invoke(Call.java:2425)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at test.TstLinux.main(TstLinux.java:56)
{http://xml.apache.org/axis/}hostname:LN-CRM-APP
java.lang.NullPointerException
at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
at org.apache.axis.client.Call.invoke(Call.java:1828)
at test.TstLinux.main(TstLinux.java:56)
Caused by: java.lang.NullPointerException
at java.security.SecureRandom.nextBytes(SecureRandom.java:292)
at org.apache.axis.utils.SessionUtils.generateSessionId(SessionUtils.java:62)
at org.apache.axis.SOAPPart.<init>(SOAPPart.java:164)
at org.apache.axis.Message.setup(Message.java:377)
at org.apache.axis.Message.<init>(Message.java:246)
at org.apache.axis.client.Call.invoke(Call.java:2425)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
... 1 more
ringa_lee2017-04-17 17:40:46
由于java.security.SecureRandom在linux上依赖于/dev/random (linux随机数生成机制参见这里),因此在出现问题的服务器上运行测试程序后运行测试脚本,结果如下:
[java] view plain copy
haitao-yao@haitaoyao-laptop:/data/develop/java/jre/lib/security$ jps && lsof /dev/random
7399 Jps
7382 TestRandom
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 7382 haitao-yao 4r CHR 1,8 0t0 4402 /dev/random
因此断定是由于随机数生成策略的问题。
google一下发现jetty的这个bug(Jetty HashSessionIdManager hangs on startup),也有人在jdk的bug database中提出过这个问题(参见这里),简单介绍一下:
java.security.SecureRandom依赖与/dev/random 生成随机数,可能由于系统interrupt不足,导致在jdk在使用/dev/random时卡死。jetty无法启动,最后导致整个namenode启动卡死。
解决方案在sun的bug database中也已经有人给出,即在java程序启动参数中添加:-Djava.security.egd=file:/dev/urandom,使用/dev/urandom生成随机数。
/dev/random和/dev/urandom的差异分析请参见这里 , 不再多说。
总结:
hadoop通过http协议提供html页面暴露系统内部状态,这在分布式系统的设计中是个非常好的feature,但是由于集成了jetty,而集成的jetty在hadoop中可配置性又不强,才暴露了这个问题。非常不理解为什么hadoop不使用独立的线程去启动内部的jetty,毕竟这并不是namenode的主要功能,因为这样的附属功能影响了系统的核心功能,未免有些得不偿失。