java.rmi.ConnectException: Connection refused to host:

最近用了java的rmi还是不错的,遇到的问题参考网上的文章解决的,做个记录

引自 http://hi.baidu.com/wangdefu/blog/item/4e1e041f8d5bdacaa7866987.html

可以参考Sun的资料去理解rmi http://java.sun.com/developer/onlineTraining/rmi/RMI.html

写一个rmi客户端程序,你可能会收到如标题这样的异常。这个问题其实是由rmi服务器端程序造成的。

客户端程序向服务端请求一个对象的时候,返回的stub对象里面包含了服务器的hostname,客户端的后续操作根据这个hostname来连接服务器端。要想知道这个hostname具体是什么值可以在服务器端bash中打入指令:
hostname -i

如果返回的是127.0.0.1,那么你的客户端肯定会抛如标题的异常了。

解决这个问题有两个方式:
1 修改/etc/hosts
找到127.0.0.1       hostxxxxx这样的字样。把127.0.0.1改成真实的,可供其他机器连接的ip。

这样客户端就能得到真实的ip了。

2 在rmi服务器端程序启动脚本中加上两行,显式指定hostname。我的脚本:
hostname=`hostname`

java -cp $CLASSPATH -Djava.rmi.server.codebase=$codebase -Djava.security.policy=$PROJECT_HOME/se_server/conf/se_server.policy -Djava.rmi.server.hostname=$hostname com.abc.server.StartServer > $PROJECT_HOME/se_server/logs/init.log 2>&1 &

不过该方式有个局限,其他机器肯定能识别ip,但是可能无法识别hostname。

当然,你也可以直接写死这个hostname,比如:-Djava.rmi.server.hostname=xxx.xxx.xxx.xxx。 这样最省力,就是少点灵活性.
 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cnhome/archive/2009/09/02/4512191.aspx

----------------------------------------------------------------------------------------------------------------------------------------------------------

RMI invocation attempts connecting to 127.0.0.1



Hi
I've exported a bean by using the RmiServiceExporter, and tries to access this bean through the RmiProxyFactoryBean. This works fine when client and server is on the same host, but fails with the following exception when client is set up on a different host. I have ofcourse set the RmiProxyFactoryBean.serviceUrl correctly, and the remote object is found, but as the exception shows it is the invocation of a method on the remote object that fails with a connect failure to 127.0.0.1. Why is the loopback address being used? I found from the javadocs of RmiServiceExporter a suggestion to set -Djava.rmi.server.host , but this does not seem to help. [using spring 2.0]
Exception in thread "main" org.springframework.remoting.RemoteConnectFailureE xception: Cannot connect to remote service [rmi://bernt:2000/Admin]; nested exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused
Caused by: java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEnd point.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection( TCPChannel.java:185)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCP Channel.java:171)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:9 4)
at org.springframework.remoting.rmi.RmiInvocationWrap per_Stub.invoke(Unknown Source)
at org.springframework.remoting.rmi.RmiClientIntercep tor.doInvoke(RmiClientInterceptor.java:400)
at org.springframework.remoting.rmi.RmiClientIntercep tor.doInvoke(RmiClientInterceptor.java:344)
at org.springframework.remoting.rmi.RmiClientIntercep tor.invoke(RmiClientInterceptor.java:259)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :185)
at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:209)
at $Proxy0.settle(Unknown Source)
[CUT]
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl .java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSoc ketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.j ava:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.j ava:366)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at java.net.Socket.<init>(Socket.java:366)
at java.net.Socket.<init>(Socket.java:179)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.cre ateSocket(RMIDirectSocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.cre ateSocket(RMIMasterSocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEnd point.java:569)
... 24 more 
---------



Finally figured this out. RMI uses the following method to obtain a server hostname:
http://java.sun.com/j2se/1.4.2/docs/...ml#nethostname
In my case the IP returned was 127.0.0.1 due to the setup on my linux box
(see http://www.jguru.com/faq/view.jsp?EID=790132).
By changing the OS setup i got the correct external IP address returned.
Strange though that neither -Djava.rmi.server.host=$HOSTNAME nor -Djava.rmi.server.useLocalHostname=true did the job. 

 



Well, since I didn't have time to wait for a reply, I went ahead and banged my head against it for a little while and figured out what to do.
After re-reading the links from thosmas' posts, I realized that it was the hosts file on the server that needed to be fixed. 
If your hosts file has the first line as:
Code:
127.0.0.1    localhost  {hostname}

you must remove the {hostname} from that first line and add another line like:
Code:
{actual ip address}   {hostname}

That worked for me. 

---------------------------------------------------------------------------------------------------------------------------------------------------------

其他参考:

==============================================================================================

==============================================================================================

How does RMI obtain a server hostname in each of the versions of the JDK?

Methods that RMI uses to obtain a server hostname in each of the versions of the JDK: 
JDK v1.1
RMI relied upon 
java.net.InetAddress.getLocalHost()
to return a fully qualified domain name. 
InetAddress
objects initialized local hostnames in a static block of code, performing a reverse lookup on the local IP address to retrieve a local hostname. However, on machines that were not connected to the network, this behavior caused the program to hang while 
InetAddress
looked for a hostname that could not be found. 
JDK v1.1.1-1.1.6
To work around the JDK v1.1 problem on stand-alone systems, 
InetAddress
was modified in JDK v1.1.1 to only retrieve the [potentially unqualified] hostname returned from a native system call, which did not attempt to consult a name service. RMI was not modified to compensate for this change since the property 
java.rmi.server.hostname
allowed users to override incorrect hostnames provided by 
InetAddress
. RMI made no attempt to consult a name service and could default to using unqualified hostnames. 
Later versions
To compensate for the many problems that were generated by the v1.1.1 change in functionality of 
InetAddress
, the following behavior has been integrated into the most recent versions of the JDK:

RMI will use an IP address or a fully qualified domain name to identify a machine that serves a remote object. Server hostnames are initialized to the value obtained by performing the following actions:


By default, RMI uses the IP address of the server host as the server name for remote references. 
If the property 
java.rmi.server.hostname
is set, RMI will use its value as the server hostname, and will not attempt to find a fully qualified domain name through any other method. This property takes precedence over all other means of finding an RMI server name. 
If the property 
java.rmi.server.useLocalHostname
is set to 
true
(by default, the value of this property is 
false
), RMI applies the following routine to obtain a hostname for the RMI server: 
If the value returned by the 
InetAddress.getLocalHost().getHostName()
method contains a "." character, then RMI will assume that this value is the server's fully qualified domain name and will use it as the server hostname. 
Otherwise, RMI will spawn a thread to query the local name service for the fully qualified domain name of the RMI server. If the name service takes too long to return, or the name service returns but its response does not contain a "." then RMI will use the server's IP address obtained from 
InetAddress.getLocalHost().getHostAddress()

Users can override the default time (10 seconds or 10000 milliseconds) that RMI will look for a fully qualified domain name by setting the following property: 
sun.rmi.transport.tcp.localHostnameTimeOut
=timeOutMillis 
where timeOutMillis is the time that RMI will wait in milliseconds. For example:

            java -Dsun.rmi.transport.tcp.localHostnameTimeOut=2000 MyServerApp
        


When using activatable remote objects, it is recommended that RMI servers set the value of the 
java.rmi.server.useLocalHostname
property to 
true
. In general, hostnames are more stable than IP addresses. Activatable remote objects tend to last longer than transient remote objects (for example,  surviving a reboot). An RMI client will be more likely to locate a remote object over a long period of time if it uses a qualified hostname rather than an explicit IP address.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值