Java 防止RMI导出异常

Java 防止RMI导出异常,java,registry,rmi,Java,Registry,Rmi,我有一个简单的客户机/服务器程序,它使用以下命令将服务器对象添加到ServerLauncher类中的注册表中: try { Registry reg = LocateRegistry.createRegistry(1099); reg.rebind("ServerObject", new Server()); System.out.println("Server set up completed."); } catch (Remo

我有一个简单的客户机/服务器程序,它使用以下命令将服务器对象添加到ServerLauncher类中的注册表中:

try {
        Registry reg = LocateRegistry.createRegistry(1099);
        reg.rebind("ServerObject", new Server());
        System.out.println("Server set up completed.");
    } 
    catch (RemoteException e) {
        e.printStackTrace();
    } 
然后,客户端通过以下方式获得对RMI对象的引用:

Registry reg = LocateRegistry.getRegistry("localhost", 1099);
remoteServerObject = (ServerInterface) reg.lookup("Server");
程序运行良好,客户端可以成功连接到服务器。但是,每当我多次启动ServerLauncher时,就会出现以下错误:

java.rmi.server.ExportException:端口已在使用:1099;嵌套异常是: java.net.BindException:地址已在使用中:JVM\u Bind

此异常实际上不会影响我的程序的功能,就像第二个ServerLauncher引发此异常一样,服务器对象仍在第一个ServerLauncher放置的注册表中,因此客户端仍然能够连接到服务器。 然而,我想知道是否有办法防止这种异常发生。reg.rebind不应该替换注册表上的内容吗?因此,如果端口1099已经在使用中,这应该无关紧要?我不明白为什么会抛出此异常

try {
        Registry reg = LocateRegistry.createRegistry(1099);
        reg.rebind("ServerObject", new Server());
        System.out.println("Server set up completed.");
    } 
    catch (RemoteException e) {
        Registry reg = LocateRegistry.getRegistry(1099);
        reg.rebind("ServerObject", new Server());
        System.out.println("Server already installed.");
        e.printStackTrace();
    } 
reg.rebind不应该替换注册表上的内容吗

是的

因此,如果端口1099已经在使用中,这应该无关紧要

非顺序逻辑。异常不是由
rebind()
引发的,而是由
createRegistry()引发的。

我不明白为什么会抛出此异常

try {
        Registry reg = LocateRegistry.createRegistry(1099);
        reg.rebind("ServerObject", new Server());
        System.out.println("Server set up completed.");
    } 
    catch (RemoteException e) {
        Registry reg = LocateRegistry.getRegistry(1099);
        reg.rebind("ServerObject", new Server());
        System.out.println("Server already installed.");
        e.printStackTrace();
    } 
端口1099已被另一个JVM中的注册表使用,因此无法创建另一个注册表

这里有不止一个问题。
注册表
变量应该是静态的,否则可能会被垃圾收集。如果要重用现有注册表,只需调用
LocateRegistry.getRegistry():
类似以下内容:

static Registry registry;

try {
    registry = LocateRegistry.createRegistry(1099);
} catch (ExportException exc) {
    registry = LocateRegistry.getRegistry(1099);
}
registry.rebind("ServerObject", new Server());
System.out.println("Server set up completed.");

您在LocateRegistry.createRegistry(1099)上得到异常;不需要重新绑定。检查stacktrace中的行号。