I've run into a problem that has stumped me for a couple of weeks.
I'm working on URLyBird 1.3.1 and am using a remote design identical to the latest DennyDvD project in SCJD Exam with J2SE 5 as shown below.
suncertify.db packageAll methods throw RecordNotFoundException except one that throws DuplicateKeyExceptionsuncertify.remote packageAll methods with signature identical to those found in DBMainI run into the following errors for each of the DBMain methods when I compile RoomDatabaseImpl with rmic:I have the standalone client working and the RMI server running. However, when I start the RMI server and then the network client, I run into the exceptionsI understand that all remote methods must be declared to throw RemoteException in the corresponding remote interface. However, when I try to add throwing a RemoteException to the methods in RoomDatabaseImpl, the NetBeans compiler give me an error because I'm overriding a method in DBMain that doesn't throw a RemoteException. I don't understand why I'm running into this problem when the DennysDVD class matching mine, DvDDatabaseImpl class has methods that throw RemoteException although none of the methods in the DBClient class throw a RemoteException. I have been able to get the Denny's DVD project running in my Netbeans IDE.
I'm open to major changes in my RMI design but, if possible, I'd like to first find out what's wrong with my current design and make minor changes.
Any sugestions/questions you have are welcome! Thanks! Bill Rowell
[Andrew: Changed tabs to 2 spaces to attempt to reduce horizontal wrappping. Forced some wrapping for the same reason.] [ June 04, 2006: Message edited by: Andrew Monkhouse ]
Joined: Apr 20, 2006
I started implementing the RMI part of my project today and came across the exact same problem in the last hour!
It works for the DennysDVD class because all the methods on its interface throw IOException which is a superclass of RemoteException.
I'm still working on a solution to this so can only clarify the confusion re DennysDVD.
Jeroen T Wenting
Joined: Apr 21, 2006
There's a few ways around it. 1) create a wrapper of some sort around your DB that transports it to the server and does throw RemoteException. 2) create a completely separate calling mechanism for the database which on the server gets translated into calls to a DB. The client would in that scenario never see a DB at all.
Joined: Apr 20, 2006
I've been working on this today again and come up with a solution (albeit one which is not ideal). My assumption is that i cannot change the provided interface (DB) at all so i created a duplicate interface which extends Remote and throws the relevant RemoteExceptions. I also create a RemoteWrapper which implements the original DB interface and wraps the new RemoteDB interface. A factory on the client side will decide whether to get a local or network version i.e. the DB or the RemoteWrapper and return a DB to the caller. So far it seems to work well enough.
The downsides that i can see: 1) 2 interfaces where normally 1 should be sufficient 2) Extra complexity of wrapper class 3) The RemoteExceptions have to be handled somehow inside the wrapper (as DB doesn't throw them). I think my solution to this will be to create an exception class which extends RuntimeException as i am aversed to using any existing checked exceptions when they don't really apply (and some of my methods throw no exceptions so at least this approach has consistency).
I did try a couple of other methods but this is the best i could come up with which would work. Can anyone see other issues with this approach that i haven't noticed (especially any showstoppers...)?