绑定 RMI 服务时抛出 ServerException
我正在尝试构建简单的回显服务器作为 RMI 应用程序(按照 Sun 教程中所述逐步进行)。
所有源代码如下所示,非常简单:
package test;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface EchoServer extends Remote {
public String sendString (String str) throws RemoteException;
}
package test;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class EchoServerImpl extends UnicastRemoteObject implements EchoServer {
public EchoServerImpl () throws RemoteException {
super ();
}
public String sendString (String str) throws RemoteException {
return str.toUpperCase();
}
}
package test;
import java.rmi.Naming;
public class RMIServer {
public RMIServer () {
try {
EchoServer eServer = new EchoServerImpl ();
Naming.rebind ("rmi://localhost:1099/EchoService", eServer); // <--exception
} catch (Exception e) {
e.printStackTrace ();
}
}
public static void main(String[] args) {
new RMIServer ();
}
}
我用 rmic 编译代码,然后看到文件 EchoServerImpl_Stub.class。之后我运行“rmiregistry”,然后启动 RMIServer。在那一刻,我看到 ServerException:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: test.EchoServerImpl_Stub at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Unknown Source) at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359) at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) at java.rmi.Naming.rebind(Naming.java:160) at test.RMIServer.(RMIServer.java:10) at test.RMIServer.main(RMIServer.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90) Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: test.EchoServerImpl_Stub at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Unknown Source) at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.ClassNotFoundException: test.EchoServerImpl_Stub at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClassInternal(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at sun.rmi.server.LoaderHandler.loadClass(Unknown Source) at sun.rmi.server.LoaderHandler.loadClass(Unknown Source) at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source) at java.rmi.server.RMIClassLoader.loadClass(Unknown Source) at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) ... 12 more
我认为这是一个常见问题,它可能与错误的部署有关。如何修复它?
I'm trying to build simple echo server as RMI application (step by step as it's described in Sun tutorial).
All source code is shown below, it's very simple:
package test;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface EchoServer extends Remote {
public String sendString (String str) throws RemoteException;
}
package test;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class EchoServerImpl extends UnicastRemoteObject implements EchoServer {
public EchoServerImpl () throws RemoteException {
super ();
}
public String sendString (String str) throws RemoteException {
return str.toUpperCase();
}
}
package test;
import java.rmi.Naming;
public class RMIServer {
public RMIServer () {
try {
EchoServer eServer = new EchoServerImpl ();
Naming.rebind ("rmi://localhost:1099/EchoService", eServer); // <--exception
} catch (Exception e) {
e.printStackTrace ();
}
}
public static void main(String[] args) {
new RMIServer ();
}
}
I compile code with rmic and I see file EchoServerImpl_Stub.class. After that I run 'rmiregistry' and then I start RMIServer. And at that moment I see ServerException:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: test.EchoServerImpl_Stub at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Unknown Source) at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359) at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) at java.rmi.Naming.rebind(Naming.java:160) at test.RMIServer.(RMIServer.java:10) at test.RMIServer.main(RMIServer.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90) Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: test.EchoServerImpl_Stub at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Unknown Source) at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.ClassNotFoundException: test.EchoServerImpl_Stub at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClassInternal(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at sun.rmi.server.LoaderHandler.loadClass(Unknown Source) at sun.rmi.server.LoaderHandler.loadClass(Unknown Source) at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source) at java.rmi.server.RMIClassLoader.loadClass(Unknown Source) at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) ... 12 more
I think it's a common problem and it's probably connected with wrong deploying. How to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为这是您的 rmiregistry 类路径。
test.EchoServer
接口需要可供 rmiregistry 本身访问。在运行rmiregistry之前设置您的CLASSPATH
环境变量,例如此外,rmic是Java 5之前的遗留问题。没有必要不再运行它了。只需正常运行服务器和客户端,代理就会动态创建。
问候,
MK
I think it's your rmiregistry classpath. The
test.EchoServer
interface needs to be accessible to the rmiregistry itself. Set yourCLASSPATH
environment variable before you run up the rmiregistry e.g.Also, rmic is a hangover from before Java 5. It isn't necessary to run it anymore. Just run your server and client as normal and the proxies will be created dynamically.
Regards,
MK