简体   繁体   English

Java RMI,一个接口在Web服务器上作为远程发布,但它不应该

[英]Java RMI, an interface is published as remote on the webserver, while it shouldn't

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. 该项目只是一个简单的项目,所以我熟悉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. 我把项目划分为3个java项目。 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). 服务器(拥有MockStockMarket和Fund),客户端(具有GUI类和与服务器通信的类:BannerController)和具有客户端和服务器所需接口的项目(IStockMarket和IFund)。

I want my bannerController to talk with the StockMarket so that the bannercontroller gets the funds. 我希望我的bannerController与StockMarket交谈,以便bannercontroller获得资金。 This is done using getFunds() : ArrayList. 这是使用getFunds():ArrayList完成的。

As you can see, StockMarket should be Remote, and the Fund should be Serializable. 如您所见,StockMarket应该是远程的,基金应该是可序列化的。

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. IStockMarket(按预期)和IFund(不是预期的)都变得远程。 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. 为了记录:Fund实现了IFund,它扩展了Serializable(所以没有远程),MockStockMarket扩展了UnicastRemoteObject并实现了扩展Remote的IStockMarket。

Here is a screenshot for the Webserver publishing both interfaces: http://imageshack.us/m/194/4755/rmibothinterfacespublis.png . 以下是Webserver发布两个界面的屏幕截图: http//imageshack.us/m/194/4755/rmibothinterfacespublis.png

For the soure code: https://rapidshare.com/files/2085773800/stockmarket.zip 对于源代码: https ://rapidshare.com/files/2085773800/stockmarket.zip

Binding an RMI service to a port is different than the Web Server publishing files. 将RMI服务绑定到端口与Web Server发布文件不同。 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. 您附加的屏幕截图显示您的IStockMarket.class和IFund.class文件作为HTTP资源公开,与“绑定”RMI服务没有任何关系。 Feel free to add more details to the question if my interpretation is wrong here and I'll try answering them. 如果我的解释错误,请随意添加更多详细信息,我会尝试回答它们。

Both IStockMarket (as intended) AND IFund (not as intended) become remote. IStockMarket(按预期)和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. 客户端需要IFund,大概是因为它出现在IStockMarket接口中。 You appear to be using the codebase feature. 您似乎正在使用代码库功能。 From the point of view of codebase the Registry is a client too. 从代码库的角度来看,Registry也是一个客户端。 So the Registry downloaded IFund.class and IStockMarket.class. 因此,注册表下载了IFund.class和IStockMarket.class。 That doesn't make IFund 'become remote' in any way shape or form. 这并不能使IFund以任何形式或形式变得“遥远”。

Oke I found it on the oracle site: http://download.oracle.com/javase/tutorial/rmi/implementing.html . 我在oracle网站上找到了它: 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. Web服务器正在发布我的IFund(非远程)接口,因为它是通过RMI方法传递的。 The my client needs the IFund to use the passed object. 我的客户端需要IFund来使用传递的对象。 I thought this was enough for RMI to work. 我认为这足以让RMI发挥作用。

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: 这很容易:

if (System.getSecurityManager() == null) 
{
    System.setSecurityManager(new SecurityManager());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM