wood burning stoves*
The moose likes Distributed Java and the fly likes RMI-beginner problem involving RemoteException Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Distributed Java
Bookmark "RMI-beginner problem involving RemoteException" Watch "RMI-beginner problem involving RemoteException" New topic
Author

RMI-beginner problem involving RemoteException

Stephen Bloch
Ranch Hand

Joined: Aug 19, 2003
Posts: 48
I'm trying to write my first RMI application, modelling it after the DVD database in Habibi, Patterson, & Camerlengo's SCJD Exam book.

That example has a package sampleproject.db, which knows nothing about RMI, Sockets, or anything like that; in particular, the package includes an interface DBClient which provides the basic database operations but doesn't mention RemoteException.

In the sampleproject.remote package is an interface named DVDDatabaseRemote which implements Remote and DBClient and has nothing in between the curly-braces. A class named DVDDatabaseImpl extends UnicastRemoteObject and implements DVDDatabaseRemote; its various methods throw RemoteException, as required. So far this makes sense to me, and it works: I can javac everything, rmic DVDDatabaseImpl, start the server, run the client, and they talk to one another (at least on the same machine -- I haven't tried it across machines yet).

So I tried something similar. The package edu.adelphi.sbloch.bank, which knows nothing about RMI, contains an interface named AccountDBInterface providing basic bank-account operations. The package edu.adelphi.sbloch.remote contains an interface named RemoteDBInterface which implements Remote and AccountDBInterface and has nothing between the curly braces. A class named RemoteDBImpl extends UnicastRemoteObject and implements RemoteDBInterface. Its constructor throws RemoteException -- no problem -- but when I add "throws RemoteException" to any of the other method headers, I get a compile error that this clause is not compatible with the throws clause in AccountDBInterface. If I leave out the "throws RemoteException", javac likes it but rmic rejects it.

Does the throws clause in a method implementation have to exactly match that in the interface? If so, why does the sample project compile? If not, why doesn't my code compile?


SCJP 1.4
Nathan Pruett
Bartender

Joined: Oct 18, 2000
Posts: 4121

Yes, throwing exceptions are considered part of the method signature, and exceptions can't be added if the interface is to be implemented correctly. The example project wouldn't build like you describe it... could there be some confusion with similiarly named interfaces/methods? Some of which wrap the RemoteExceptions?


-Nate
Write once, run anywhere, because there's nowhere to hide! - /. A.C.
Stephen Bloch
Ranch Hand

Joined: Aug 19, 2003
Posts: 48
OK, I figured it out. The DBClient interface never mentions RemoteException, but all of its methods throw IOException, which is RemoteException's superclass. So that's why the sample project compiles. My project doesn't, because the methods as I originally wrote them didn't throw IOException. (I was more interested in the RMI aspect than the database aspect, so I wrote a quick-and-dirty in-memory "database" that didn't do any I/O, just to see whether I could get RMI working.)

So I can fix it by changing my interface to throw IOException (or RemoteException or something), even though the original, non-networked implementation of the interface had no need for IOExceptions.

The question remains: what would I do if I wanted to RMI-ize an interface written by somebody else, to whom it never occurred that somebody might write a remote or otherwise I/O-dependent implementation of it? Is there any way to do this without copying and modifying the interface (which makes every OO cell of my body rebel)?
[ November 24, 2004: Message edited by: Stephen Bloch ]
Nathan Pruett
Bartender

Joined: Oct 18, 2000
Posts: 4121

The way I've usually done it is make two adapters - one to wrap and convert the non-remote interface to a remote interface, and one to wrap and convert the remote interface back to a non-remote interface... I call this a "double-wrapper adapter", but I don't know if the pattern exists under another name elsewhere.

Basically -


Usually I prefer to re-throw the RemoteException as an exception created for and used by the application, or I make some kind of generic error-handler that pops up a dialog or something, and send the RemoteException to it to pop up some kind of "Network Down" error message.

Also, things get interesting when non-serializable return types and parameters come into play - you'll have to make adapters for any of those also, and have the client adapter and server adapter cast them back and forth.

I admit that it is kind of crappy OO to copy the methods and have a remote and non-remote version - but this is the best that I've come up with so far... also note that this isn't the preferred way to do RMI - it's basically a workaround for when you can't change the existing interface for one reason or another.
Stephen Bloch
Ranch Hand

Joined: Aug 19, 2003
Posts: 48
OK, that makes sense, although it is sorta ugly. Thanks!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: RMI-beginner problem involving RemoteException
 
Similar Threads
NX: RMI Question from Max Book
Question about camerlengo's book
NX: Question on Max's DVD project
Implementing Data interface in local and network mode
Why have an interface DvdDatabaseRemote