【发布时间】:2014-04-11 12:16:00
【问题描述】:
我有一个 java rmi 服务器和一个 java rmi 客户端在两台不同的机器上。
服务器基本上是一个 fibonacy 计算器。它接收一堆数字并根据它们计算斐波那契数列。
客户端只需发送一堆数字供服务器计算。
FiboServer 项目由三个类组成:
- IFibonacci.java:一个接口
- Fibonacci.java:实现之前定义的接口
- FibonacciServer.java:有主服务器,运行服务器
FibonacciServer.java:
package fiboserver;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class FibonacciServer {
public static void main(String args[]){
if (System.getSecurityManager() == null) {
System.setProperty("java.security.policy", "server.policy");
System.setSecurityManager(new SecurityManager());
}
try{
IFibonacci fib = new Fibonacci();
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.createRegistry(1099);
registry.rebind("fibonacci", fib);
System.out.println("Fibonacci Server ready.");
}catch(RemoteException rex){
System.err.println("Exception in Fibonacci.main " + rex);
}
}
}
客户端项目只有一个类:FibonacciClient.java。
FibonacciClient.java:
package fiboclient;
import fiboserver.IFibonacci;
import java.math.BigInteger;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class FibonacciClient {
public static void main(String[] args) {
if (System.getSecurityManager() == null) {
System.setProperty("java.security.policy", "client.policy");
System.setSecurityManager(new SecurityManager());
}
try{
//args[0] = server Public IP
Registry registry = LocateRegistry.getRegistry(args[0]);
IFibonacci calculator = (IFibonacci) registry.lookup("fibonacci");
//the rest of the args are just numbers to calculate
for(int i = 1; i < args.length; i++){
try{
BigInteger index = new BigInteger(args[i]);
BigInteger f = calculator.getFibonacci(index);
System.out.println("The " + args[i] + "th Fibonacci number "
+ "is " + f);
}catch(NumberFormatException e){
System.err.println(args[i] + " is not an integer.");
}
}
}catch(RemoteException e){
System.err.println("Remote object threw exception " + e);
} catch (NotBoundException e) {
System.err.println("Could not find the requested remote object on "
+ "the server: " + e);
}
}
}
两个项目都有一个策略文件,服务器有一个server.policy,客户端有一个client.policy 文件。两个文件的内容相同:
grant{
permission java.security.AllPermission;
};
我正在使用 java -jar FiboServer.jar -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=12.34.56.789 在服务器机器中启动 FiboServer
我正在使用java -jar FiboClient.jar 12.34.56.789 1 2 3 4 5 启动客户端。
服务器启动没有问题。但是当我启动客户端时,我得到了错误:
Remote object threw exception java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: fiboserver.IFibonacci
对 StackOverflow 的搜索使我确信这与 RMI 注册表错误或策略文件错误有关。但是我知道策略文件被正确读取,我认为它们没有任何错误。
我做错了什么?为什么这不起作用?
编辑:
IFibonacci.java:
package fiboserver;
import java.math.BigInteger;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IFibonacci extends Remote{
public BigInteger getFibonacci(int n) throws RemoteException;
public BigInteger getFibonacci(BigInteger n) throws RemoteException;
}
JAR 文件:
FibonacciClient.jar 的内容:
|META-INF
|----Manifest.mf
|fiboclient
|----FibonacciClient.class
FibonacciServer.jar 的内容:
|META-INF
|----manifest.mf
|fiboserver
|----IFibonacci.class
|----FibonacciServer.class
|----Fibonacci.class
【问题讨论】:
-
您正在远程注册表中绑定
Fibonaci对象,但尝试在客户端中查找IFibonacci对象。另外,IFibonacci类是否存在于客户端中?? -
@prasanth 世界上每个 RMI 程序都这样做。实现对象不在注册表中,在客户端也不可用。它是远程的,可以通过其远程接口访问。这就是整个想法。
-
类
IFibonacci在服务器中可用吗?您是否在注册表中绑定了正确的对象并从客户端查找相同的对象?? -
@prasanth 如果该类在服务器上不可用,它将无法启动。他正在绑定正确的对象并正确查找它。请停止猜测。
-
在客户端或服务器中某处提到的类不可用。你可能想调查一下。为了您的信息,我不是在猜测。我试图通过指出您可能无意中错过的内容来帮助您