Java RMI 简单的 Hello World 程序抛出 RemoteException

标签 java rmi remoteexception

我有一个奇怪的问题。 我正在尝试使用 RMI 编写一个简单的 Hello World java 程序。 这是我的文件,全部属于同一个包:

Hello.java:

package com.something;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Hello extends Remote{
    String hello() throws RemoteException;
}

服务器.java

package com.something;
import com.something.Hello;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class Server implements Hello{

    @Override
    public String hello() throws RemoteException {
        return "hello world!!!!";
    }
public static void main (String args[]) throws RemoteException{

        //System.setProperty("java.rmi.server.hostname", "10.0.0.5");
                 if (System.getSecurityManager() == null) {
                        System.setSecurityManager(new SecurityManager());
                    }
                    try {
                        String name = "Hello";
                        Hello s = new Server();
                        Hello stub =
                            (Hello) UnicastRemoteObject.exportObject(s, 0);
                        Registry registry = LocateRegistry.getRegistry(8888);



                        registry.rebind(name, stub);
                        System.out.println("Hello bound");
                    } catch (Exception e) {
                        System.err.println("Hello exception:");
                        e.printStackTrace();
                    }
    }        

}       

客户端.java:

package com.something; 


import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;



public class Client {
    public static void main(String args[]) {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
        try {
            String name = "Hello";
            Registry registry = LocateRegistry.getRegistry("localhost"); 

            Hello h = (Hello) registry.lookup(name);
            System.out.println(h.hello());   
        } catch (Exception e) {
            System.err.println("My exception:");
            e.printStackTrace();
        }
    }    
}

在运行代码之前,在终端中运行:

rmiregistry 8888

我使用以下标志运行 java 代码: -Djava.security.policy=/Users/nataliazon/Documents/workspace/SiecioweRMI/src/server.policy

这是我的 server.policy 文件:

grant {
   permission java.security.AllPermission;
};

当我这样运行服务器程序时,抛出以下异常:

Hello exception:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.something.Hello
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:400)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:248)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
    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 com.something.Server.main(Server.java:30)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.something.Hello
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:390)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:248)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.ClassNotFoundException: com.something.Hello
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:247)
    at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:709)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:653)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:590)
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628)
    at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294)
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238)
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1530)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1492)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    ... 12 more

客户端程序抛出这个:

My exception:
java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:601)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
    at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at com.something.Client.main(Client.java:18)
Caused by: java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
    at java.net.Socket.connect(Socket.java:529)
    at java.net.Socket.connect(Socket.java:478)
    at java.net.Socket.<init>(Socket.java:375)
    at java.net.Socket.<init>(Socket.java:189)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
    ... 5 more

如何解决这个问题?

最佳答案

java.lang.ClassNotFoundException: com.something.Hello

注册表和客户端的类路径中没有该类。

对于注册表,最简单的解决方案是在服务器 JVM 中启动它。通过LocateRegistry.createRegistry() :或者以该类位于其类路径上的方式启动它;有多种方法可以实现这一点。

java.rmi.ConnectException: Connection refused to host: localhost

这是由于在调用 Naming.lookup() 时指定“localhost”而不是服务器主机造成的或调用 LocateRegistry.getRegistry() 时在调用 Registry.lookup() 之前。注册表并不无处不在,它位于服务器主机上。

注意,您不需要 SecurityManager除非您正在使用 RMI 代码库功能或者您对此有其他要求。

关于Java RMI 简单的 Hello World 程序抛出 RemoteException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10752288/

相关文章:

java - 在 JXTree 中搜索

java - 无法从静态上下文引用非静态变量 "youngestAge"。任何帮助表示赞赏! :)

java - 安卓 : What kind of encryption do I choose to send my data safely to an app using WCF?

java - RMI:远程对象的字段是否被序列化并发送到客户端?

java - 使 Java RMI 在 netbeans 7 上运行

android - 在 Asynctask 中处理远程异常

java - 使用 FileInputStream 和 FileOutputStream 作为缓冲区

java - 在 Spring 中使用 RMI 公开多个对象

java - 无法解析类型 java.rmi.RemoteException。它是从 java 中必需的 .class 文件错误中间接引用的

java - 无法摆脱著名的DataStreamer异常:org.apache.hadoop.ipc.RemoteException:错误