本例是java rmi的一个实例,是java网络编程精简里面的:
服务器:SmipleServer
import javax.naming.*;public class SimpleServer{ public static void main( String args[] ){ try{ HelloService service1 = new HelloServiceImpl("service1"); HelloService service2 = new HelloServiceImpl("service2"); System.setProperty( "java.rmi.server.hostname", "127.0.0.1"); Context namingContext=new InitialContext(); namingContext.rebind( "rmi://127.0.0.1:8000/HelloService1", service1 ); namingContext.rebind( "rmi:HelloService2", service2 );/* namingContext.rebind( "rmi://localhost:8000/HelloService1", service1 ); namingContext.rebind( "rmi://localhost:8000/HelloService1", service2 );*/ System.out.println( "服务器注册了两个HelloService对象" ); }catch(Exception e){ e.printStackTrace(); } }}
接口:HelloService
import java.util.Date;
import java.rmi.*;public interface HelloService extends Remote{ public String echo(String msg) throws RemoteException; public Date getTime() throws RemoteException;}
具体服务:HelloServiceImpl
import java.util.Date;
import java.rmi.*;import java.rmi.server.UnicastRemoteObject;public class HelloServiceImpl extends UnicastRemoteObject implements HelloService{ private String name; public HelloServiceImpl(String name)throws RemoteException{ this.name=name; } public String echo(String msg)throws RemoteException{ System.out.println(name+":调用echo()方法"); return "echo:"+msg +" from "+name; } public Date getTime()throws RemoteException{ System.out.println(name+":调用getTime()方法"); return new Date(); }} 运行服务器:SimpleServer输出的异常信息为:
javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect] at com.sun.jndi.rmi.registry.RegistryContext.rebind(RegistryContext.java:142) at com.sun.jndi.toolkit.url.GenericURLContext.rebind(GenericURLContext.java:231) at javax.naming.InitialContext.rebind(InitialContext.java:408) at com.net.rmi.hello.SimpleServer.main(SimpleServer.java:13)Caused by: java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: java.net.ConnectException: Connection refused: connect at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:601) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184) at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322) at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) at com.sun.jndi.rmi.registry.RegistryContext.rebind(RegistryContext.java:140) ... 3 moreCaused by: java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java: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:180) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595) ... 8 more
为了定位异常,我们要把异常翻译过来,翻译成类自然语言,使得我们能够易于接受和理解:
javax.naming.ServiceUnavailableException
根据JDK的描述,该异常在javax.naming包里面,异常的继承结构为:
java.lang.Exception
javax.naming.NamingException
javax.naming.ServiceUnavailableException
为了了解这个类,我们先要了解其父:
javax.naming.NamingException:
此异常是 Context 和 DirContext 接口中的操作抛出的所有异常的超类。失败的特性由子类的名称描述。
此异常捕获指出操作失败处的信息,比如解析最后进行到的位置。
这就是我们能够看懂的信息了,其他的我们暂时不知道它在说什么东西,暂且不管它。
javax.naming.ServiceUnavailableException:
当试图与目录或命名服务通信,而该服务不可用时,抛出此异常。该服务可能因为各种原因而不可用。例如,服务器可能太忙而无法为请求提供服务,
或者服务器可能没有为向某些请求提供服务而注册等等。
我们看异常信息的下一句话:
[Root exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1;
nested exception is: java.net.ConnectException: Connection refused: connect]
这个翻译过来就是最根本的或者说最原始的异常是java.rmi.ConnectException.相关的描述是连接被拒绝。而这个异常中嵌套的异常是
java.net.ConnectException 连接被拒绝。
java.rmi.ConnectException的父类为java.rmi.RemoteException
RemoteException
是许多与通信相关的异常的通用超类,这些异常可能会在执行远程方法调用期间发生。
远程接口(扩展 java.rmi.Remote
的接口)的每个方法必须在其 throws 子句中列出 RemoteException
。
java.rmi.Connection:
如果拒绝远程主机对连接的远程方法调用,则抛出 ConnectException
。