我写了这个小程序来说明我的问题(它本身没有多大意义,但这没关系):
public class Stuff extends UnicastRemoteObject implements IStuff{
HashMap<Entry, String> map = new HashMap<Entry, String>();
@Override
public void exec(IStuff s) throws RemoteException{
System.out.println(s.getEntryMap(this.e1));
System.out.println(s.getEntryMap(this.e2));
System.out.println(s.getEntryMap(this.e3));
}
}
假设有一个类Entry(也扩展UnicastRemoteObject
)并且在构造函数中填充了HashMap。
还有:
public class MyRegistry extends UnicastRemoteObject implements IMyRegistry{
@Override
public void register(IStuff s) throws RemoteException{
s.exec(s);
}
}
我现在打电话
MyRegistry r = new MyRegistry();
r.register(new Stuff());
按预期打印地图内容。
如果MyRegistry
实例在服务器上运行,则会发生另一件事:
服务器启动MyRegistry
:
Registry reg = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
reg.rebind("Reg",new MyRegistry());
客户端使用它:
IMyRegistry reg = (IMyRegistry) Naming.lookup("Reg");
reg.register(new Stuff());
现在打印的全部是:
null
null
null
这是有道理的,因为Registry获取了一个Remote Stub,并将其传递给exec
方法。 exec
方法本身远程调用getEntryMap
,因为它收到了Stub of Stuff。因此,使用e1,e2和e3的Stub调用getEntryMap
方法。当然,地图没有Stubs的条目,但是没有实际对象的条目。 IEntry
中收到的getEntryMap
实例不是实例条目。
我的问题现在是:
exec
在任何情况下都能显示正确的条目。有没有办法将存根转换为实际对象?基本铸造显然不起作用。似乎这应该是可能的,因为Stuff
,map
和条目存在于客户端上,并且exec
在客户端上执行。getEntryMap() instanceof Entry
中的每个Entry存根都不存在,甚至是同一个对象?修改,附加信息:
创建的实际Stuff
对象如下所示:
Stuff[UnicastServerRef [liveRef: [endpoint:[192.168.1.68:60327](local),objID:[-1ff30562:13f0eb9f539:-7ff9, 219978949996152147]]]]
exec
中的存根看起来像这样:
Proxy[IStuff,RemoteObjectInvocationHandler[UnicastRef [liveRef: [endpoint:[192.168.1.68:60327](remote),objID:[-1ff30562:13f0eb9f539:-7ff9, 219978949996152147]]]]]
基本上,它归结为:
Stuff
是UnicastRemoteObject
,并且客户端无论如何都会跟踪导出的对象,因此似乎不太难将存根解析为实际对象。