2

我之前在许多项目中成功使用过 RMI(在 Java 6 中),其中有明确定义的客户端/服务器关系。当我在以前的项目中使用它时,我创建了一个定义明确的接口 JAR,它部署到客户端和服务器,并使用“-Djava.rmi.server.codebase=... -Djava”启动 RMI 服务器.rmi.server.hostname=localhost -Djava.security.policy=...\server.policy"

我现在正在尝试使用 RMI 执行双向通信,以构建基本集群。具体来说,我希望 B(工人“客户端”)向 A(中央“服务器”)注册。但是,我希望 B 实现 java.rmi.Remote 接口并将自己的引用传回给 A。这样做的主要动机是: * A 不需要知道 B 的所有实例驻留在哪里(它们可以是互联网上的任何地方,如果需要的话!) * 一旦 B 的实例向 A 注册,那么 A 就可以控制 B(即,按照 A 的决定在 B 上执行任务)。

我的问题是,每当我尝试将此远程接口 (B) 作为参数传递回 A 时,我会在 B 上收到以下异常(但如果我传递 null,远程调用将成功发生,这使得这种解释不太可能:http ://download.oracle.com/javase/1.4.2/docs/guide/rmi/codebase.html#section6):

ERROR com.mycompany.server.dao.ServerInterfaceImpl - RMI registerWorker() failed: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.mycompany.worker.MyWorker (no security manager: RMI class loader disabled)

其中:* A(实现)= com.mycompany.server.dao.ServerInterfaceImpl * B = com.mycompany.worker.MyWorker

(Q1) 是否可以按照我的描述进行操作?有人能写出我所描述的超基本版本吗(即客户端 B 向服务器 A 注册,然后将对 B 的远程接口的引用传递给 A,以便 A 可以控制 B)?我最初以为我有一些模糊的错字/配置问题,但我开始这个任务是不可能的......

(Q2)如果我想要做的事情是不可能的,另一个想法是将B的每个实例变成一个RMI Server,并在B连接到A之后让A连接到B。我想要的主要原因要做到这一点,我希望 A 和(每个实例)B 将被互联网分开,并且只有 A 会有一个公共互联网地址(每个 B 实例都没有公共 IP 地址,并且可能被困在各种防火墙,这样 B 连接到 A 比反之更容易)... 归根结底,一旦 B 连接到 A,我只想促进双向通信!

(Q3)我正在考虑在 A 和 B 之间进行心跳。一种可能性是使用每个 B 的这些心跳来轮询 A 任何出色的工作......我更希望 A 异步控制 B,但是......

4

1 回答 1

0

java.lang.ClassNotFoundException: com.mycompany.worker.MyWorker

这意味着该类不存在于试图反序列化它的节点上。所以放在那里。

在防火墙允许的情况下,您正在尝试的将起作用。如果涉及互联网,您基本上可以忘记它。

于 2011-08-17T08:19:54.780 回答