Search code examples
javarmiserializable

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. 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


Solution

  • 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:

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