首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java问题:无法解决线程“主”java.rmi.NotBoundException: Server中的异常

Java问题:无法解决线程“主”java.rmi.NotBoundException: Server中的异常
EN

Stack Overflow用户
提问于 2020-11-08 14:51:20
回答 1查看 590关注 0票数 0

我得到了以下错误:

代码语言:javascript
复制
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)

有人能看看我的代码并告诉我哪里出了问题吗?我会非常感激的。甚至会给我一个小小的提示什么的,我就那么绝望了。

代码语言:javascript
复制
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");
    }
}
代码语言:javascript
复制
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;
    }
}
代码语言:javascript
复制
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 material, String schaltung, 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;
    }
}
代码语言:javascript
复制
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");
    }
}
代码语言:javascript
复制
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;
    }
}
代码语言:javascript
复制
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 material, String schaltung, String griff ) throws RemoteException;
}

我知道密码不完美。我将更改它,但最重要的是让客户机和服务器独立运行。我的当事人很遗憾没能跑。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-08 20:27:24

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

  1. 创建“远程”接口。 您的接口RMI_Interface没有问题。这里没什么可做的。
  2. 创建一个实现远程接口的类。 我使构造函数为空。(其余代码不变。)
代码语言:javascript
复制
public ConfigImpl() throws RemoteException {
    // Empty.
}
  1. 创建一个RMI服务器。在这里我做了一些改动。
代码语言:javascript
复制
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,因此不需要使用这一行代码:

代码语言:javascript
复制
Runtime.getRuntime().exec("rmiregistry 1099");
  1. 运行服务器,即java server.FahrradServer (我假设您知道实际启动服务器所需的正确命令。) 请注意,服务器程序将永远运行-除非您杀死它。
  2. 给客户写信。客户机将在单独的JVM中运行,因此客户端需要一个main()方法,以便您可以通过java命令启动它。
代码语言:javascript
复制
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,即
代码语言:javascript
复制
public class Fahrrad implements java.io.Serializable
  1. 现在您可以启动您的RMI客户端,例如java client.RMIClient

请参阅Oracle教程的RMI跟踪。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64739444

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档