Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Only my defined exception cause compile error

 
David Chan
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
public interface Database {
public List readAll() throws IOException;
}
public class DatabaseAdapter implements Database {
public List readAll() throws RemoteException,
IOException {

return new Vector();
}
}
public interface DatabaseService extends Remote, Database {
}
public class DatabaseServiceImpl extends UnicastRemoteObject
implements DatabaseService {
public List readAll() throws RemoteException,
IOException {

return dbAdapter.readAll();
}
}
Above files can be compiled fine. The problem is that if the IOException is replaced by DataAccessException which is created by myself, it appears compilation error when compile DatabaseServiceImpl file:
javac DatabaseAdapter.java [OK]
javac DatabaseServiceImpl.java
DatabaseServiceImpl.java:9: readAll() in suncertify.remote.DatabaseServiceImpl cannot implement readAll() in suncertify.db.Database; overridden method does not throw java.rmi.RemoteException public class DatabaseServiceImpl extends UnicastRemoteObject
Here is the exception source code:
package suncertify.db;
public class DataAccessException extends Exception
{
public DataAccessException() {
super();
}
public DataAccessException(String message) {
super(message);
}
public DataAccessException(Throwable cause) {
super(cause);
}
public DataAccessException(String message, Throwable cause) {
super(message, cause);
}
}

Is there any problem in my defined exception?
Thanks for you help.

David
 
Nicholas Cheung
Ranch Hand
Posts: 4982
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi David,

This cannot be complied for sure.
It is becos, the methods in parent class/interface does NOT define to throw RemoteException, as such, all methods of its subclasses/sub-interfaces canNOT throw RemoteException as well.
If you want the methods of subclass throw RemoteException, methods in super interface MUST declare to throw RemoteException.
Nick.
 
David Chan
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, I have made some mistakes when post the source code previously. The problem is that:
- public List readAll() throws IOException
[All compilation is OK]
- if change to: public List readAll() throws DataAccessException
[javac DatabaseAdapter.java OK]
[javac DatabaseServiceImpl.java FAIL]
DatabaseServiceImpl.java:6: readAll() in DatabaseServiceImpl cannot implement readAll() in Database; overridden method does not throw java.rmi.RemoteException public class DatabaseServiceImpl extends UnicastRemoteObject
Please help, thank you.

David

Here is tested source code:
***********************************************************
import java.io.*;
import java.util.*;
public interface Database {
public List readAll() throws IOException;
}
***********************************************************
import java.io.*;
import java.util.*;
public class DatabaseAdapter implements Database {
public DatabaseAdapter() {
}
public List readAll() throws IOException {
return new Vector();
}
}
***********************************************************
import java.rmi.*;
public interface DatabaseService extends Remote, Database {
}
***********************************************************
import java.io.*;
import java.util.*;
import java.rmi.*;
import java.rmi.server.*;
public class DatabaseServiceImpl extends UnicastRemoteObject
implements DatabaseService {
DatabaseAdapter dbAdapter;
public DatabaseServiceImpl() throws RemoteException {
dbAdapter = new DatabaseAdapter();
}
public List readAll() throws RemoteException,
IOException {
return dbAdapter.readAll();
}
}
***********************************************************
public class DataAccessException extends Exception {
public DataAccessException() {
super();
}
public DataAccessException(String message) {
super(message);
}
public DataAccessException(Throwable cause) {
super(cause);
}
public DataAccessException(String message, Throwable cause) {
super(message, cause);
}
}
 
David Chan
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

- if change to: public List readAll() throws DataAccessException

I mean readAll() is changed to throw DataAccessException in ALL files. (i.e. replace words IOException by DataAccessException)
Hope that it will make clear, thanks.

David
 
Nicholas Cheung
Ranch Hand
Posts: 4982
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi David,
I cannot see the difference between your previous code and the updated code.
For your updated code, you have:

Since DatabaseServiceImpl implements DatabaseService, while DatabaseService extends Database, i.e. actually,
DatabaseServiceImpl implements Database.
According to the code above, it surely cannot compile becos readAll() method in Database does NOT throw RemoteException, while the readAll() method in DatabaseServiceImpl does!
So, it is not allow!
DatabaseAdapter can be compiled successfully becos the signature of readAll() method in it is exactly the same as Database.
Nick.
[ January 16, 2004: Message edited by: Nicholas Cheung ]
 
George Marinkovich
Ranch Hand
Posts: 619
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi David,
I copied your code into a single file and made some minor changes to make it compile (mostly dropping public modifier from class and interface delcarations). I then got the same error you were seeing. I made your
DataAccessException inherit from IOException rather than Exception. As a consequence the code below compiles without error. However, since IOException doesn't have IOException(Throwable) or IOException(String, Throwable) constructors I had to comment out those calls.

Hope this helps,
George
[ January 16, 2004: Message edited by: George Marinkovich ]
 
David Chan
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, maybe I posted too many source code such that you can find the diff. The main difference between 2 posts is that in updated version the readAll() does not throw RemoteException because Database interface RemoteException does not (as you said).
To simulate my problem is very simple. Copy and paste into java files (totally there are 5 files). Type javac *.java, first time all compilation is OK and you will not get error. Then replace all words IOException by DataAccessException, compile once again, it will appear the error message.
Thanks for your help.

David
*** Previous ****************************************************
public class DatabaseAdapter implements Database {

public List readAll() throws RemoteException,
IOException {

return new Vector();
}
}
*** Updated *****************************************************
import java.io.*;
import java.util.*;
public class DatabaseAdapter implements Database {
public DatabaseAdapter() {
}

public List readAll() throws IOException {

return new Vector();
}
}
 
David Chan
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
George,
Thanks for your reply and your solution.
I think it is OK that DataAccessException inherit from IOException to solve the problem. But what if I want to throw BookedAlreadyException, it is not OK to inherit from IOException because record booked already is related to IO error, it just because the application "rule" does not allow.
Is it exception limitation when used with RMI?

David
 
George Marinkovich
Ranch Hand
Posts: 619
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi David,
This is the inheritance hierarchy of the RemoteException class:

Having DataAccessException inherit from IOException rather then Exception has the following consequence: DataAccessException now inherits from IOException, the same class from which RemoteException inherits.
So instead of:

we have:

Why this makes a difference I'm not exactly sure. It does seem to make a difference though. It leads me to this observation:
I've never seen a successful RMI implementation of a class wherein the class methods throw exceptions unless those exceptions are IOExceptions or exceptions that inherit from IOException.
Maybe someone more knowledgeable than me can give a concise reason for this observation (or alternatively refute the observation).
Hope this helps,
George
 
George Marinkovich
Ranch Hand
Posts: 619
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi David,
Regarding the BookedAlreadyException:
I think we may have different assignments (I had B&S Contractors); it sounds to me like you might have the URLyBird assignment.
So I may not understand the BookedAlreadyException requirement. Since I don't have this understanding, I question whether this exception really needs to exist. A user books room A for customer 1, a user seeing that room A has already been booked for customer 1, decides to book it for customer 2 (thereby overwriting customer 1's reservation). I can think of valid reasons why this scenario should be allowed. Therefore I don't see the need for the BookedAlreadyException. Why is it needed? I would leave it up to the user. Just tell the user that if they book a room that someone else has already booked then they'd better have a good reason.
For instance, customer 1 calls up and reserves room A. Customer 2 calls up and would like to book room A, but is told that room A is already booked. Customer 1 calls back and says that due to a car accident he can no longer use room A and wants to cancel his reservation. The user calls back Customer 2 and tells him that room A is available now. Customer 2 still wants it so the user books room A for Customer 2, overwriting Customer 1's reservation. Is this a bad thing?
Hope this helps,
George
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic