【问题标题】:ClassNotFoundException with RMI带有 RMI 的 ClassNotFoundException
【发布时间】:2016-06-15 08:52:28
【问题描述】:

我用 RMI 在 netbeans 中编写了一个程序,客户端出错

错误:

java.rmi.UnmarshalException:解组返回错误;嵌套的 例外是:java.lang.ClassNotFoundException: rmiserver.Message (没有安全管理器:RMI 类加载器已禁用)在 sun.rmi.registry.RegistryImpl_Stub.lookup(未知来源)

但是服务器没有任何错误!

界面代码:

 package rmiclient;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Message extends Remote {
    void sayHello(String name) throws RemoteException;
}

接口实现是:

 package rmiserver;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class MessageImpl extends UnicastRemoteObject implements Message {

    public MessageImpl() throws RemoteException {       
    }

    @Override
    public void sayHello(String name) throws RemoteException {
        System.out.println("hello "+name);
    }

}

服务器代码是:

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

public class Main {

    private void startServer(){
        try {
            // create on port 1099
            Registry registry = LocateRegistry.createRegistry(1099);

            // create a new service named myMessage
            registry.rebind("myMessage", new MessageImpl());
        } catch (Exception e) {
            e.printStackTrace();
        }     
        System.out.println("system is ready");
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.startServer();
    }
}

客户端代码是:

package rmiclient;
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Main {

    private void doTest(){

        try {

            // fire to localhost port 1099
            Registry myRegistry = LocateRegistry.getRegistry("127.0.0.1", 1099);


            // search for myMessage service
            Message impl = (Message) myRegistry.lookup("myMessage");

            // call server's method        
            impl.sayHello("edwin");

            System.out.println("Message Sent");
        } catch (Exception e) {
            e.printStackTrace();
        }       
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.doTest();
    }
}

谢谢:)。

【问题讨论】:

  • 而且代码无法编译。
  • 我的代码编译好了!构建成功(总时间:0 秒)。但不会运行
  • 这个代码没有。你在包rmiclient中有Message,在包rmiserver中有实现它的服务器,并且没有import rmiclient.*语句;

标签: java rmi classnotfoundexception


【解决方案1】:

在您的堆栈跟踪中:

java.lang.ClassNotFoundException: rmiserver.Message

但是根据您提供的数据,您的Message 接口已使用包package rmiclient; 进行了声明,并且您尚未创建任何rmiserver.Message 类。

更正包名。

【讨论】:

  • 谢谢!但在我的服务器和客户端以及接口和实现的原始代码中使用了“package rmiserver;”
  • 好吧,你还有rmiclient.Message,错误消息仍然显示rmiserver.Message,所以这个答案仍然正确。您的客户端也包含在 rmiserver 包中,如果您有 rmiclient 包,这没有任何意义。并且代码无法编译。 所以肯定不是真正的代码。
  • 我有 2 个来自消息方法的副本。一个用于客户端,一个用于服务器!所以我需要在客户端导入“rmiclient”并为服务器导入“rmiserver”
  • 我有两个包裹。 rmiclient 和 rmiserver。在 rmiclient 中是 "message" 和 "main" 。在 rmiserver 中是 "message" 和 "main" 和 "messageimpl"
【解决方案2】:

我有两个包裹。 rmiclient 和 rmiserver。在 rmiclient 中是 "message" 和 "main" 。在 rmiserver 中是 "message" 和 "main" 和 "messageimpl"

那是你的问题。这不满足合同。您不能只是将Message 复制到另一个包并期望它与原始包相同。远程存根实现与远程对象相同的远程接口。不是另一个包中具有相同名称的另一个接口。

您必须将rmiserver.Message 部署到客户端。就像错误消息所说的那样,真的。

【讨论】:

  • 这意味着我必须为服务器和客户端有两个不同的接口?
  • 我无法理解您为什么或如何可能会问这个问题。这就是你已经在做的事情。我的回答的重点是完全相反。 您必须在服务器和客户端之间共享​​> same 接口。你正在尝试的是没有意义的。我以为我已经说清楚了。
  • 您应该考虑在此处投票和/或接受您认为有用的任何答案。
猜你喜欢
  • 2012-05-11
  • 2011-11-15
  • 2014-06-14
  • 2012-07-01
  • 2023-03-21
  • 1970-01-01
  • 2017-01-16
相关资源
最近更新 更多