【问题标题】:ServerException is being thrown while binding RMI service绑定 RMI 服务时抛出 ServerException
【发布时间】:2010-12-02 00:22:27
【问题描述】:

我正在尝试将简单的回显服务器构建为 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 更多

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

【问题讨论】:

    标签: java exception rmi


    【解决方案1】:

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

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

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

    问候, MK

    【讨论】:

    • 运行rmic必要的,除非你满足UnicastRemoteObject的Javadoc前言中提到的条件,而OP没有做到这一点。
    猜你喜欢
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 2015-02-03
    • 1970-01-01
    • 2011-09-29
    • 2016-09-24
    • 1970-01-01
    相关资源
    最近更新 更多