0

我正在尝试将简单的回显服务器构建为 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;嵌套异常是:
    java.rmi.UnmarshalException:解组参数错误;嵌套异常是:
    java.lang.ClassNotFoundException: test.EchoServerImpl_Stub
    在 sun.rmi.server.UnicastServerRef.oldDispatch(未知来源)
    在 sun.rmi.server.UnicastServerRef.dispatch(未知来源)
    在 sun.rmi.transport.Transport$1.run(未知来源)
    在 java.security.AccessController.doPrivileged(本机方法)
    在 sun.rmi.transport.Transport.serviceCall(未知来源)
    在 sun.rmi.transport.tcp.TCPTransport.handleMessages(未知来源)
    在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(未知来源)
    在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(未知来源)
    在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(未知来源)
    在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源)
    在 java.lang.Thread.run(未知来源)
    在 sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
    在 sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
    在 sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359)
    在 sun.rmi.registry.RegistryImpl_Stub.rebind(未知来源)
    在 java.rmi.Naming.rebind(Naming.java:160)
    在 test.RMIServer.(RMIServer.java:10)
    在 test.RMIServer.main(RMIServer.java:17)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    在 java.lang.reflect.Method.invoke(Method.java:597)
    在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
引起:java.rmi.UnmarshalException:错误解组参数;嵌套异常是:
    java.lang.ClassNotFoundException: test.EchoServerImpl_Stub
    在 sun.rmi.registry.RegistryImpl_Skel.dispatch(未知来源)
    在 sun.rmi.server.UnicastServerRef.oldDispatch(未知来源)
    在 sun.rmi.server.UnicastServerRef.dispatch(未知来源)
    在 sun.rmi.transport.Transport$1.run(未知来源)
    在 java.security.AccessController.doPrivileged(本机方法)
    在 sun.rmi.transport.Transport.serviceCall(未知来源)
    在 sun.rmi.transport.tcp.TCPTransport.handleMessages(未知来源)
    在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(未知来源)
    在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(未知来源)
    在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(未知来源)
    在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源)
    在 java.lang.Thread.run(未知来源)
引起:java.lang.ClassNotFoundException:test.EchoServerImpl_Stub
    在 java.net.URLClassLoader$1.run(未知来源)
    在 java.security.AccessController.doPrivileged(本机方法)
    在 java.net.URLClassLoader.findClass(未知来源)
    在 java.lang.ClassLoader.loadClass(未知来源)
    在 java.lang.ClassLoader.loadClass(未知来源)
    在 java.lang.ClassLoader.loadClassInternal(未知来源)
    在 java.lang.Class.forName0(本机方法)
    在 java.lang.Class.forName(未知来源)
    在 sun.rmi.server.LoaderHandler.loadClass(未知来源)
    在 sun.rmi.server.LoaderHandler.loadClass(未知来源)
    在 java.rmi.server.RMIClassLoader$2.loadClass(未知来源)
    在 java.rmi.server.RMIClassLoader.loadClass(未知来源)
    在 sun.rmi.server.MarshalInputStream.resolveClass(未知来源)
    在 java.io.ObjectInputStream.readNonProxyDesc(未知来源)
    在 java.io.ObjectInputStream.readClassDesc(未知来源)
    在 java.io.ObjectInputStream.readOrdinaryObject(未知来源)
    在 java.io.ObjectInputStream.readObject0(未知来源)
    在 java.io.ObjectInputStream.readObject(未知来源)
    ... 12 更多  

我认为这是一个常见问题,可能与错误部署有关。如何解决?

4

1 回答 1

0

我认为这是您的rmiregistry类路径。rmir​​egistry本身test.EchoServer需要可以访问该接口。在运行rmiregistry之前设置环境变量,例如CLASSPATH

C:\>set CLASSPATH="MyBinFolder"
C:\>rmiregistry

此外,rmic是 Java 5 之前的遗留物。不再需要运行它。只需正常运行您的服务器和客户端,代理就会被动态创建。

问候, MK

于 2009-09-28T14:50:22.337 回答