我决定编写 RMI(来自书中),代码也来自书中。我用 rmic 创建了 Stub,并启动了 rmiregistry,但是当我决定编写 java Start Server 时,我遇到了问题,实际上这是我面临的问题: java -classpath D:\RMI AddServer 异常:java.rmi.ServerException:服务器线程中发生RemoteException; n 预计的异常(exception)是: java.rmi.UnmarshalException:解码参数时出错;嵌套异常(exception) 化是: java.lang.ClassNotFoundException:AddServerImpl_Stub 请我需要帮助,因此我损失了很多时间:(
AddServerIntf.java
package rmi.app;
import java.rmi.*;
public interface AddServerIntf extends Remote {
double add(double d1,double d2) throws RemoteException;}
AddServerImpl
package rmi.app;
import java.rmi.*;
import java.rmi.server.*;
public class AddServerImpl extends UnicastRemoteObject implements AddServerIntf {
public AddServerImpl() throws RemoteException {}
public double add(double d1, double d2) throws RemoteException {
return d1+d2;
}
}
添加服务器
package rmi.app;
import java.net.*;
import java.rmi.*;
public class AddServer {
public static void main(String[] args) {
try {
AddServerImpl addServerImpl = new AddServerImpl();
Naming.rebind("AddServer", addServerImpl);
}
catch (Exception e){
System.out.println("Exception:"+e);
}
}
}
添加客户端
package rmi.app;
import java.rmi.Naming;
public class AddClient {
public static void main(String[] args) {
try{
String addServerURL= "rmi://"+args[0]+ "/AddServer";
AddServerIntf addServer =(AddServerIntf)Naming.lookup(addServerURL);
System.out.println("The first number is:"+args[1]);
double d1= Double.valueOf(args[1]).doubleValue();
System.out.println("The second number is:"+args[2]);
double d2= Double.valueOf(args[2]).doubleValue();
System.out.println("the sum is:"+ addServer.add(d1,d2));
}
catch(Exception e){
System.out.println("Exception : "+ e);
}
}
}
最佳答案
我也在编写一个 Java RMI 应用程序,在让它工作之前我经历了很多事情。经过大量研究和尝试和错误,我得到了这个“食谱”:
- 不安装 SecurityManager;
- 不要使用策略文件;
- 确保要从一台虚拟机移动到另一台虚拟机的类位于其中 客户端和服务器类路径(或在同一个 jar/war 中)。
- 如果您使用 hibernate 进行数据库访问,请将 jar 放入 客户也是。 Hibernate“改变”了原有的类和客户端 将需要它来反序列化它;
- 如果您还在服务器端使用 Spring,如果您遇到 ClassNotFoundException,则可能会在客户端中包含 spring-orm 和 spring-data-jpa jar随后是 JpaObjectRetrievalFailureException;
- 我没有在 jar 之外运行任何东西(根本没有 rmi 服务);
- 我没有创建 stub ,因为我使用的是 Java 6。
我的服务器纯粹是这样做的:
try {
try {
LocateRegistry.createRegistry(SERVER_PORT);
} catch (RemoteException e) {
LocateRegistry.getRegistry(SERVER_PORT);
e.printStackTrace();
}
System.setProperty("java.rmi.server.hostname", SERVER_HOST);
connectionRequestHandler = new ConnectionRequestHandlerImpl();
dataRequestHandler = new DataRequestHandlerImpl();
String rmiUrl = "rmi://" + SERVER_HOST + ":" + SERVER_PORT + "/";
Naming.rebind(rmiUrl + "ConnectionRequestHandler", connectionRequestHandler);
Naming.rebind(rmiUrl + "DataRequestHandler", dataRequestHandler);
} catch (RemoteException e1) {
e1.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
然后在客户端我正在做:
String rmiUrl = "rmi://" + SERVER_HOST + ":" + SERVER_PORT + "/";
try {
connectionRequestHandler = (ConnectionRequestHandler)Naming.lookup(rmiUrl + "ConnectionRequestHandler");
dataRequestHandler = (DataRequestHandler)Naming.lookup(rmiUrl + "DataRequestHandler");
} catch (MalformedURLException e) {
throw new RmiServicesDownException(e.getMessage());
} catch (RemoteException e) {
throw new RmiServicesDownException(e.getMessage());
} catch (NotBoundException e) {
throw new RmiServicesDownException(e.getMessage());
} catch (Exception e ){
e.printStackTrace();
return;
}
这就是我的工作方式。与第一个设置相比,您可能遇到的任何其他问题都很容易解决。
关于Java RMI ClassNotFound 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15576611/