This week's book giveaway is in the Other Languages forum.
We're giving away four copies of Functional Reactive Programming and have Stephen Blackheath and Anthony Jones on-line!
See this thread for details.
Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

B&S: throwing RemoteException

 
Dan Murphy
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I'm using RMI, and my remote interface looks like this



DataClient is an interface that defines the database operations I wish to make available to clients. The class which implements this interface looks like this:



I read that all methods in the remote object implementation class (i.e. RemoteDataClientImp) must throw RemoteException, but I'm able to compile RemoteDataClientImpl without any errors, how come?

Thanks in advance,
Dan
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 11945
212
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dan,

The implementation class methods do not all need to throw RemoteException. It is quite legal to have methods that are not remotely accessible (and even private methods) - none of these would need to throw RemoteException.

However all the methods in your interface must be declared to throw RemoteException, and those methods in your implementation class must obviously throw them as well.

But this will not be picked up on by the standard javac compiler - it is not aware of the RMI technology at all. The javac compiler will simply accept that you are implementing certain interfaces, and check that you are meeting standard Java rules for interfaces - the additional rules that RMI imposes cannot be checked at this stage.

When you run rmic, if you attempt to have a method in your remote interface that does not throw RemoteException (and your implementing class is not serializable) you should get errors.

Regards, Andrew
 
Dan Murphy
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Thanks for your reply Andrew. As you can see my remote interface doesn't actually declare any methods - all the methods are declared in the extended interface, DataClient. None of the methods in DataClient throw RemoteException, but presumably if all the methods in the implementation class (RemoteDataClientImpl) throw RemoteException, then rmic will compile my code?

The reason I'm presuming this will work is because this is exactly the approach taken in the SCJD book written by Mehrab Habibi (AKA Max).

Best Wishes,
Dan
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 11945
212
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dan,

The reason it works for Max's sample application (and for the one from my book) is that all the methods in the DbClient interface throw IOException - the superclass of RemoteException. (In my book we make it a bit more explicit that we are doing this, and explain why - basically it is one piece of ensuring that have a different interface / database class than is used in the real assignment.)

As for what will / will not work in your assignment: I recommend you try your code out - see what happens. You will learn far more from trying this, and exploring what happens, than by getting a simple answer from me .

Regards, Andrew
 
Ken Boyd
Ranch Hand
Posts: 329
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Andrew Monkhouse:
Hi Dan,

The reason it works for Max's sample application (and for the one from my book) is that all the methods in the DbClient interface throw IOException - the superclass of RemoteException. (In my book we make it a bit more explicit that we are doing this, and explain why - basically it is one piece of ensuring that have a different interface / database class than is used in the real assignment.)

As for what will / will not work in your assignment: I recommend you try your code out - see what happens. You will learn far more from trying this, and exploring what happens, than by getting a simple answer from me .

Regards, Andrew


I wish you can guide me little bit towards how remote/DVDConnector class pass DBClient where I have done the following

interface DVDDatabaseRemote implements Remote{

All methods with same name as DBClient throws RemoteException
}

DataDatabaseImpl extends Unicast implements DVDDatabaseRemote{
DBClient db = new DVDDatabase();

all methods are same as DBClient and calls to DVDDatabase e.g. db.getDvds()etc

}

Now in Remote/DVDConnector has to pass DBClient where I get stuck because DVDDatabaseImpl doesn't implement DBClient via DVDDatabaseRemote (this one only extends Remote as methods can throw RemoteException)

doing all this because DBClient in our assignment doesn't throw IOException??

Andrew I will appreciate your reply..

Thanks
 
Romeo Son
Ranch Hand
Posts: 92
Android Eclipse IDE Suse
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Andrew Monkhouse:
However all the methods in your interface must be declared to throw RemoteException, and those methods in your implementation class must obviously throw them as well.


Hello Andrew,

About your statement in the quote, I have some comments.
I totally agree with the first part of it, but for the second part I have a different opinion. It is legal to left out the throws clause for the implementing method because the rule says it can throw fewer exceptions than the declaring method. And second, the RemoteException is actually thrown by the RMI (transport) implementation and not by the implementing method (unless the programmer decides to throw it himself with 'throw new RemoteException()').
To finish I say that the RemoteException needs not be declared in the implementation and the code will work fine both at compile runtime.

[ March 12, 2007: Message edited by: Romeo Son ]
[ March 12, 2007: Message edited by: Romeo Son ]
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 11945
212
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ken,

I do not understand what you mean by "pass DBClient" - pass to whom?

Regards, Andrew
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 11945
212
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Romeo
I totally agree with the first part of it, but for the second part I have a different opinion. It is legal to left out the throws clause for the implementing method because the rule says it can throw fewer exceptions than the declaring method.
True
And second, the RemoteException is actually thrown by the RMI (transport) implementation and not by the implementing method (unless the programmer decides to throw it himself with 'throw new RemoteException()').
I can think of a few cases where that might be useful. But it is not strictly required for the assignment.

Regards, Andrew
[ March 12, 2007: Message edited by: Andrew Monkhouse ]
 
Ken Boyd
Ranch Hand
Posts: 329
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Andrew Monkhouse:
Hi Ken,

I do not understand what you mean by "pass DBClient" - pass to whom?

Regards, Andrew


Passing DBClient to GUIController when connection is remote


i.e. connection = sampleproject.remote.DvdConnector.getRemote(dbLocation, port);


Thanks
 
Ken Boyd
Ranch Hand
Posts: 329
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Andrew,
My question was IOException not thrown in DB interface in my assignment. Now to overcome that I have create following interfaces and classes.

1. interface AA in db package which has all methods of DB but throws IOException (remember DB methods don't throw IOException)

2. Now wrapper class BB in db package which implements AA all methods of above interface.

3. In remote package interface CCRemote implements Remote, AA { all methods throws IOException so rmic will be happy}

4. In remote package DDImpl will implements CCRemote

5. Now Connector class in remote and local packages return AA which has same methods as Data but act as a wrapper for remote and local connections.

it is working fine but need little thumps up from you

BTW: I purchase your book and so far it help me a lot with assignment.
[ March 13, 2007: Message edited by: Ken Boyd ]
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 11945
212
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ken,

That sounds good.

I have also seen an alternative where a wrapper in both client and server side bring everything back to the DBClient interface.

There are arguments for and against either way of doing it, but both have the same effective result.

Regards, Andrew
 
Ken Boyd
Ranch Hand
Posts: 329
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Andrew Monkhouse:
Hi Ken,

That sounds good.

I have also seen an alternative where a wrapper in both client and server side bring everything back to the DBClient interface.

There are arguments for and against either way of doing it, but both have the same effective result.

Regards, Andrew


Thanks Andrew. I will stick with this one and see how testing goes for locking??
 
Romeo Son
Ranch Hand
Posts: 92
Android Eclipse IDE Suse
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Andrew,

I have the same issue with IOException not specified in SUN's interface (B&S).
But instead of creating a new interface and a wrapper class, I have extended RuntimeException and created a constructor that takes IOException. So my Data class throws IOException wrapped by a RuntimeException out to the higher level (and I don't care if the higher level is RMI or the client application).

What do you think, can I go this way?

Thanks & regards.
[ March 15, 2007: Message edited by: Romeo Son ]
 
Lucy Hummel
Ranch Hand
Posts: 232
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Romeo Son:
So my Data class throws IOException wrapped by a RuntimeException out to the higher level (and I don't care if the higher level is RMI or the client application)
[ March 15, 2007: Message edited by: Romeo Son ]


Hi Romeo,

I use the same strategy. Let see if Sun likes it. :roll:

I think that is quite okay. At least the client sees what is going wrong on server side. So for debugging purpase during real life it is much easier to see what went wrong in failure cases.

Br, Lucy
 
Romeo Son
Ranch Hand
Posts: 92
Android Eclipse IDE Suse
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Lucy,

Thanks for your reply.

Today I did a quick search in the forum for this IOException issue and I have found out that others adopted this solution too.
I hope we will not loose points because of it and to me it is more straight forward than creating additional interfaces and wrapper classes.

Regards,

Romeo
 
Ken Boyd
Ranch Hand
Posts: 329
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Andrew Monkhouse:
Hi Ken,

That sounds good.

I have also seen an alternative where a wrapper in both client and server side bring everything back to the DBClient interface.

There are arguments for and against either way of doing it, but both have the same effective result.

Regards, Andrew


huu can you tell me or point out to thread where wrapper on both (client and server) bring things back to DBClient?

Thanks for your help
 
Bas ter Brugge
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Andrew Monkhouse:
Hi Ken,

That sounds good.

I have also seen an alternative where a wrapper in both client and server side bring everything back to the DBClient interface.

There are arguments for and against either way of doing it, but both have the same effective result.

Regards, Andrew



Hi all,

At the moment I extended my local adapter interface to throw IOException in all methods, so that the Remote adapter interface can throw RemoteException and the client side doesn't need a wrapper to convert the remote adapter interface back to the local adapter interface (The remote interface is an extension of the local interface). This works without any problems.

However, I'm still in doubt whether I should refactor to the client and server side adapters, since throwing IOException in the local adapter interface is no really nice solution.

I'm curious about the arguments for both solutions. Throwing IOException in the local adapter interface really makes the client side code simple and clear, but the server side interface throws exceptions without any purpose.

Is it a matter of taste?

Best regards,
Bas ter Brugge
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic