本例是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 more
Caused 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
。