微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java RMI问题:无法解决线程“ main”中的异常java.rmi.NotBoundException:服务器

如何解决Java RMI问题:无法解决线程“ main”中的异常java.rmi.NotBoundException:服务器

我遇到以下错误

Exception in thread "main" java.rmi.NotBoundException: Server
at java.rmi/sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:234)
at java.rmi/sun.rmi.registry.RegistryImpl_Skel.dispatch(RegistryImpl_Skel.java:133)
at java.rmi/sun.rmi.server.UnicastServerRef.olddispatch(UnicastServerRef.java:468)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:298)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
at java.rmi/sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:303)
at java.rmi/sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:279)
at java.rmi/sun.rmi.server.UnicastRef.invoke(UnicastRef.java:380)
at java.rmi/sun.rmi.registry.RegistryImpl_Stub.lookup(RegistryImpl_Stub.java:123)
at client.RMIClient.startClient(RMIClient.java:17)
at client.FahrradClient.main(FahrradClient.java:12)

有人可以看看我的代码并告诉我哪里出了问题吗?我将不胜感激。甚至会给我一个小小的小费或者是我的绝望。

package server;
import shared.RMI_Interface;

import java.io.IOException;
import java.rmi.AlreadyBoundException;
import java.rmi.remoteexception;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class FahrradServer {
    public static void main(String[] args) throws IOException,AlreadyBoundException {
        RMI_Interface server = new ConfigImpl();
        Registry registry = LocateRegistry.createRegistry(1099);
        Runtime.getRuntime().exec("rmiregistry 1099");
        registry.bind("Server",server);
        System.out.println("Server started");
    }
}

package client;
import shared.Fahrrad;
import shared.RMI_Interface;

import java.rmi.*;
import java.rmi.registry.*;

public class RMIClient {
    private RMI_Interface server;

    public RMIClient() {}

    public void startClient() throws remoteexception,NotBoundException {
        Registry registry = LocateRegistry.getRegistry("localhost",1099);
        server = (RMI_Interface)registry.lookup("Server");
    }

    public Fahrrad configureFahrrad(String lenkertyp,String material,String schaltung,String griff ) {
        Fahrrad result = null;
        try {
            result = server.configureFahrrad(lenkertyp,material,schaltung,griff);
        } catch (remoteexception e) {
            e.printstacktrace();
            throw new RuntimeException("Could not contact server");
        }
        return result;
    }
}

package server;

import shared.Fahrrad;
import shared.RMI_Interface;
import java.rmi.remoteexception;
import java.rmi.server.UnicastRemoteObject;

public class ConfigImpl implements RMI_Interface {

    public void ConfigImpl() throws remoteexception {
        UnicastRemoteObject.exportObject(this,0);
    }

    @Override
    public Fahrrad configureFahrrad(String lenkertyp,String griff ) throws remoteexception {
        Fahrrad f = new Fahrrad();
        f.setLenkertyp(lenkertyp);
        f.setGriff(griff);
        f.setMaterial(material);
        f.setSchaltung(schaltung);

        if (!lenkertyp.equals( "Faltbarlenker")  && !lenkertyp.equals( "Rennradlenker") && !lenkertyp.equals( "Bullhornlenker")) {
            throw new IllegalArgumentException("Ungültiger Lenktypinput");
        }

        if (!material.equals( "Aluminium") && !material.equals( "Stahl") && !material.equals( "Kunststoff")){
            throw new IllegalArgumentException("Ungültiges Material!");
        }

        if (!schaltung.equals("Kettenschaltung") && !schaltung.equals( "Tretlagerschaltung") && !lenkertyp.equals( "Nebenschaltung")) {
            throw new IllegalArgumentException("Ungültige Schaltung!");
        }

        if (!griff.equals( "Kunststoffgriff") && !griff.equals( "Ledergriff") && !lenkertyp.equals( "Schaumstoffgriff")) {
            throw new IllegalArgumentException("Ungültige Schaltung!");
        }

        if (lenkertyp.equals("Faltbarlenker") || lenkertyp.equals("Rennradlenker")) {
            if (!material.equals( "Aluminium") && !material.equals( "Kunststoff")) {
                throw new IllegalArgumentException(lenkertyp + " kann nur aus Aluminium oder Kunststoff bestehen.");
            }
        }

        if (material.equals("Stahl")) {
            if (!schaltung.equals("Kettenschaltung")) {
                throw new IllegalArgumentException("Materialtyp "+ material + " kann nur Kettenschaltung haben!");
            }
        }

        if (material.equals("Kunststoff")) {
            if (griff.equals("Kunststoffgriff")) {
                throw new IllegalArgumentException("Nur Kunststoffmaterial kann Kunststoffgriff haben!");
            }
        }

        if (lenkertyp.equals( "Bullhornlenker") || lenkertyp.equals("Faltbarlenker")) {
            if (griff.equals("Ledergriff")) {
                throw new IllegalArgumentException("Nur Rennladlenker können Ledergriffe haben!");
            }
        }
        return f;
    }
}

package server;
import shared.RMI_Interface;

import java.io.IOException;
import java.rmi.AlreadyBoundException;
import java.rmi.remoteexception;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class FahrradServer{
    public static void main(String[] args) throws IOException,server);
        System.out.println("Server started");
    }
}

package shared;

public class Fahrrad {
    public String lenkertyp;
    public String material;
    public String schaltung;
    public String griff;

    public void setLenkertyp(String lenkertyp){
        this.lenkertyp=lenkertyp;
    }

    public String getLenkertyp() {
        return lenkertyp;
    }

    public void setMaterial(String material){
        this.material=material;
    }

    public String getMaterial() {
        return material;
    }

    public void setSchaltung(String schaltung) {
        this.schaltung=schaltung;
    }

    public String getSchaltung() {
        return schaltung;
    }

    public void setGriff(String griff){
        this.griff=griff;
    }

    public String getGriff() {
        return griff;
    }
}

package shared;

import java.rmi.Remote;
import java.rmi.remoteexception;

// Creating Remote interface for our application
public interface RMI_Interface extends Remote {
    public Fahrrad configureFahrrad(String lenkertyp,String griff ) throws remoteexception;
}

我知道代码并不完美。我将对其进行更改,但最重要的是使客户端和服务器独立运行。可悲的是我的客户无法运行。

解决方法

创建RMI应用程序时应遵循的步骤。

  1. 创建“远程”界面。
    您的界面RMI_Interface正常。这里没事。
  2. 创建一个实现远程接口的类。
    我使构造函数为空。 (其余代码保持不变。)
public ConfigImpl() throws RemoteException {
    // Empty.
}
  1. 创建一个RMI服务器。在这里,我做了一些更改。
package server;

import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import shared.RMI_Interface;

public class FahrradServer {

    public static void main(String[] args) {
        try {
            ConfigImpl server = new ConfigImpl();
            RMI_Interface stub = (RMI_Interface) UnicastRemoteObject.exportObject(server,0);
            Registry registry = LocateRegistry.createRegistry(1099);
            registry.bind("Server",stub);
            System.out.println("Server started");
        }
        catch (AlreadyBoundException | RemoteException x) {
            x.printStackTrace();
        }
    }
}

请注意,调用方法createRegistry()将启动 rmiregistry ,因此不需要此行代码:

Runtime.getRuntime().exec("rmiregistry 1099");
  1. 运行服务器,即java server.FahrradServer
    (我假设您知道实际启动服务器所需的正确命令。)
    请注意,服务器程序将永远运行-除非将其杀死。
  2. 编写客户端。客户端将在单独的JVM中运行,因此客户端需要一种main()方法,以便您可以通过java命令启动它。
package client;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import shared.Fahrrad;
import shared.RMI_Interface;

public class RMIClient {
    private RMI_Interface server;

    public void startClient() throws RemoteException,NotBoundException {
        Registry registry = LocateRegistry.getRegistry(1099);
        server = (RMI_Interface) registry.lookup("Server");
    }

    public Fahrrad configureFahrrad(String lenkertyp,String material,String schaltung,String griff) throws RemoteException {
        return server.configureFahrrad(lenkertyp,material,schaltung,griff);
    }

    public static void main(String[] args) {
        RMIClient client = new RMIClient();
        try {
            client.startClient();
            Fahrrad f = client.configureFahrrad("Faltbarlenker","Aluminium","Kettenschaltung","Kunststoffgriff");
            System.out.println("Fahrrad: " + f);
        }
        catch (RemoteException | NotBoundException x) {
            x.printStackTrace();
        }
    }
}
  1. 由于远程接口方法的返回值是您编写的类,因此该类必须实现接口Serializable,即
public class Fahrrad implements java.io.Serializable
  1. 现在您可以启动RMI客户端,例如java client.RMIClient

请参考Oracle Java教程的RMI线索。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。