【发布时间】:2016-07-20 05:51:21
【问题描述】:
我是 Java RMI 的新手。我尝试使用 eclipse 启动简单的基本示例 java RMI。但我无法启动服务器和客户端代码。请帮我解决这个问题。
服务器代码: MyServer.java
package in.rmi.test;
import java.rmi.*;
public class MyServer {
public static void main(String args[]) {
try {
Adder stub = new AdderRemote();
Naming.rebind("rmi://localhost:5000/sonoo", stub);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Adder.java
package in.rmi.test;
import java.rmi.*;
public interface Adder extends Remote{
public int add(int x,int y)throws RemoteException;
}
AdderRemote.java
package in.rmi.test;
import java.rmi.*;
import java.rmi.server.*;
public class AdderRemote extends UnicastRemoteObject implements Adder{
private static final long serialVersionUID = 1L;
AdderRemote()throws RemoteException{
super();
}
public int add(int x,int y){
return x+y;
}
}
启动服务器时出现异常
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: in.rmi.test.Adder
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:420)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:271)
at sun.rmi.transport.Transport$2.run(Transport.java:202)
at sun.rmi.transport.Transport$2.run(Transport.java:199)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:198)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:567)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access$400(TCPTransport.java:619)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:684)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:681)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:275)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:252)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:378)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:177)
at in.rmi.test.MyServer.main(MyServer.java:11)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: in.rmi.test.Adder
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:410)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:271)
at sun.rmi.transport.Transport$2.run(Transport.java:202)
at sun.rmi.transport.Transport$2.run(Transport.java:199)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:198)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:567)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access$400(TCPTransport.java:619)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:684)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:681)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: in.rmi.test.Adder
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.rmi.server.LoaderHandler$Loader.loadClass(LoaderHandler.java:1206)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:278)
at sun.rmi.server.LoaderHandler.loadClassForName(LoaderHandler.java:1219)
at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:729)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:673)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:610)
at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:265)
at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1566)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1779)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
... 17 more
MyClient.java
package in.rmi.test;
import java.rmi.*;
public class MyClient {
public static void main(String args[]) {
try {
System.setProperty("java.security.policy", "AllPermission.policy");
System.setSecurityManager(new RMISecurityManager());
Adder stub = (Adder) Naming.lookup("rmi://localhost:5000/sonoo");
System.out.println(stub.add(34, 4));
} catch (Exception e) {
System.out.println(e);
}
}
}
【问题讨论】:
-
看起来 Adder 类没有编译:
Caused by: java.lang.ClassNotFoundException: in.rmi.test.Adder -
是的,要么找不到类定义,要么您的客户端中的类签名与您的服务器实现不同
-
我只在 Eclipse 上编译和运行这个程序。它是在eclipse上编译的。但它对 rmiregistry 不可见。重新绑定时发生这种情况。
-
当我在课堂上没有包名的情况下工作时,它工作正常。当我去打包时它会通过异常。
-
是的,那是因为你在两个实现中有不同的包名,正如上面所建议的......这两个类必须相同。为了实现这一点,制作一个 CustomCore Library ,它将保存您的所有 Base Models ,并从该库导入到服务器和客户端