Java RMI,一个接口在网络服务器上以远程方式发布,但它不应该
我遇到了一个棘手的问题,但首先让我解释一下背景。
该项目只是一个简单的项目,所以我熟悉了RMI。该项目是一个股票市场服务器和一个从服务器提取有关资金的数据的客户端。
我将该项目分为 3 个 java 项目。服务器(具有 MockStockMarket 和 Fund)、客户端(具有 GUI 类和与服务器对话的类:BannerController)以及具有客户端和服务器都需要的接口的项目(IStockMarket 和 IFound)。
我希望我的横幅控制器与股票市场对话,以便横幅控制器获得资金。这是使用 getFunds() 完成的:ArrayList。
正如您所看到的,StockMarket 应该是远程的,并且 Fund 应该是可序列化的。
问题是,由于某种原因,当我使用以下代码时:
IStockMarket market = new MockStockMarket();
Naming.rebind("rmi://localhost/StockMarket", market);
IStockMarket (按预期)和 IFound (不按预期)都变得远程。这不是我想要的。
郑重声明:Fund 实现了 IFound,它扩展了 Serialized(因此没有远程功能),MockStockMarket 扩展了 UnicastRemoteObject 并实现了 IStockMarket,它扩展了 Remote。
以下是发布两个接口的网络服务器的屏幕截图: http://imageshack.us/m/ 194/4755/rmibothinterfacespublis.png。
对于源代码: https://rapidshare.com/files/2085773800/stockmarket.zip
I'm having a nasty problem, but first let me explain the context.
The project is just a simple project so I get familiar with RMI. The project is a stockmarket server and a client that pulls data about the funds from the server.
I've divided the project in 3 java projects. The server (having MockStockMarket and Fund), the client (having GUI classes and a class to talk to the server: BannerController) and a project with the interfaces which both the client and server need (IStockMarket and IFund).
I want my bannerController to talk with the StockMarket so that the bannercontroller gets the funds. This is done using getFunds() : ArrayList.
As you can see, StockMarket should be Remote, and the Fund should be Serializable.
The problem is, for some reason when I use the following code:
IStockMarket market = new MockStockMarket();
Naming.rebind("rmi://localhost/StockMarket", market);
Both IStockMarket (as intended) AND IFund (not as intended) become remote. Which is not what I want.
For the record: Fund implements IFund, which extends Serializable (so nothing remote) and MockStockMarket extends UnicastRemoteObject and implements IStockMarket, which extends Remote.
Here is a screenshot for the Webserver publishing both interfaces: http://imageshack.us/m/194/4755/rmibothinterfacespublis.png.
For the soure code: https://rapidshare.com/files/2085773800/stockmarket.zip
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
将 RMI 服务绑定到端口与 Web 服务器发布文件不同。您所附的屏幕截图显示您的 IStockMarket.class 和 IFund.class 文件作为 HTTP 资源公开,与“绑定”RMI 服务没有任何关系。如果我的解释有误,请随时向问题添加更多细节,我会尝试回答它们。
Binding an RMI service to a port is different than the Web Server publishing files. The screenshot which you have attached shows that your IStockMarket.class and IFund.class files are exposed as HTTP resources which doesn't have anything to do with "binding" a RMI service. Feel free to add more details to the question if my interpretation is wrong here and I'll try answering them.
不,他们没有。对象只能通过导出而“变得远程”,而接口根本不会“变得远程”。客户端需要IFund,大概是因为它出现在IStockMarket界面中。您似乎正在使用代码库功能。从代码库的角度来看,注册表也是一个客户端。因此,注册中心下载了 IFound.class 和 IStockMarket.class。这并不会让IFund以任何方式“变得遥远”。
No they don't. Objects only 'become remote' by being exported, and interfaces don't 'become remote' at all. IFund is needed by the client, presumably because it appears in the IStockMarket interface. You appear to be using the codebase feature. From the point of view of codebase the Registry is a client too. So the Registry downloaded IFund.class and IStockMarket.class. That doesn't make IFund 'become remote' in any way shape or form.
好吧,我在 Oracle 网站上找到了它: http://download.oracle.com/ javase/tutorial/rmi/implementing.html。
Web 服务器正在发布我的 IFound(非远程)接口,因为它是通过 RMI 方法传递的。我的客户需要 IFound 才能使用传递的对象。我认为这足以让 RMI 工作。
我不知道的是客户端还需要下载类实现,以便它可以反序列化对象并使用复制对象的方法。为此,您必须在客户端使用安全管理器。这很简单:
Oke I found it on the oracle site: http://download.oracle.com/javase/tutorial/rmi/implementing.html.
The webserver is publishing my IFund (non remote) interface because it is passed through a RMI method. The my client needs the IFund to use the passed object. I thought this was enough for RMI to work.
What I didn't know is that the client ALSO needs downloads the class implementation so it can deserialize the object and use the methods of the copied object. For this to work you have to use a securitymanager on the client side. Which is very easy: