如何解决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应用程序时应遵循的步骤。
- 创建“远程”界面。
您的界面RMI_Interface
正常。这里没事。 - 创建一个实现远程接口的类。
我使构造函数为空。 (其余代码保持不变。)
public ConfigImpl() throws RemoteException {
// Empty.
}
- 创建一个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");
- 运行服务器,即
java server.FahrradServer
(我假设您知道实际启动服务器所需的正确命令。)
请注意,服务器程序将永远运行-除非将其杀死。 - 编写客户端。客户端将在单独的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();
}
}
}
- 由于远程接口方法的返回值是您编写的类,因此该类必须实现接口
Serializable
,即
public class Fahrrad implements java.io.Serializable
- 现在您可以启动RMI客户端,例如
java client.RMIClient
请参考Oracle Java教程的RMI线索。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。