I have a base class which implements the following interface, the methods declared on it throw the basic exception type Exception.
There are many concrete classes extending the base class and i dont want to add a try-catch block in all of them. Is there a way to handle throws without adding try-catch?
Interface
public interface IReportFactory {
public Object GetDataFromDB(Connection conn,HashMap<String,String> map) throws Exception;
public Object GetJSONString(HashMap<String,String> map) throws Exception;
}
Base class
public abstract class BaseReport implements IReportFactory{
public Connection conn;
public String acctId = FactoryReport.getAcctId();
------ I WANT TO CATCH EXCEPTION HERE ------
------ WHICH ACCURS IN OTHER CLASSES WHICH EXTENDS FROM THIS CLASSES -----
}
Example of a concrete class (there are 30)
public class GeneralRevenue extends BaseReport {
private final Logger logger = Logger.getLogger(GeneralRevenue.class);
public GeneralRevenue(Connection _conn) {
this.conn = _conn;
}
#Override
public Object GetJSONString(HashMap<String,String> params) throws Exception {
//codes
return jObj.toString();
}
#Override
public Object GetDataFromDB(Connection conn,HashMap params) throws Exception {
//codes
return RevenueList;
}
}
Just because you're extending the interface doesn't mean you have to add throws Exception, it's ok to declare your implementing class as throwing less exceptions than the interface. You just can't make the implementation throw broader exceptions than the interface.
So you could define your methods without the throws clause, like:
public Object GetJSONString(HashMap<String,String> params) {
and if there is any checked exception thrown you can rethrow it as an unchecked exception.
If you want to catch exceptions thrown by the subclass, you have to rearrange your code so that methods of the subclass are called by the super class, otherwise the super class doesn't have the opportunity to catch anything. You might consider if it makes sense to use strategies (which would let you wrap the calls to the strategies and might reduce the amount of inheritance you have to do).
Something that happens a lot is that developers use inheritance as their preferred means of extension, and (since we're always in a hurry) there's not a lot of thought about keeping concerns separated, with the result being code that's complicated and inflexible. Breaking this up along different lines of responsibility might help to make this less complicated and would probably help with the exception-throwing situation, since the different pieces would be better-focused and could throw less broad exceptions.
Why don't you create a custom RuntimeException and throw it inside the try catch block of your base class?
public class GeneralRevenue extends BaseReport {
private final Logger logger = Logger.getLogger(GeneralRevenue.class);
public GeneralRevenue(Connection _conn) {
this.conn = _conn;
}
#Override
public Object GetJSONString(HashMap<String,String> params) throws MyException {
try{
//codes
}catch(Exception e) {
throw new MyException();
}
return jObj.toString();
}
}
class MyException extends RuntimeException {
}
If you throw RuntimeException then there is no need to add the throws declaration. So for Example of you create your own RuntimeException like
class NewException extends RuntimeException{
}
Then when you add RuntimeException to your BaseClass all the other methods will not have to declare throws which will call these methods.
http://docs.oracle.com/javase/6/docs/api/java/lang/RuntimeException.html
Related
I'm writing a utility that can be called when a user-defined exception (MyException) occurs. My approach is to call this utility from constructors of MyException class. However, calling the same utility method across all constructors explicitly looks redundant. Is there a way to invoke my method from all constructors without explicitly saying MyUtil.invoke() in all these constructors?
public class MyException extends Exception {
private static final long serialVersionUID = 1L;
public MyException() {
super();
}
public MyException(final Throwable e) {
super(e);
ExceptionUtil.logExceptionToElasticSearchServer(e.getMessage());
}
public MyException(final String message) {
super(message);
ExceptionUtil.logExceptionToElasticSearchServer(message);
}
public MyException(final String message, final Throwable e) {
super(message, e);
ExceptionUtil.logExceptionToElasticSearchServer(message);
}
}
The simply way might be constructor telescoping, as in:
public MyException() {
this(null, null);
}
You only implement the last constructor taking two arguments, and all other constructors call that one!
Of course, the implicit assumption here is that your utility methods are, in the end, also coming together in the "same" call. As of now, your constructors are all calling different methods.
Beyond that, the real answer is: don't do that. A constructor creates a new object. It is not at all its job to issue a log, that goes to some server or so!
Seriously, this is a bad idea:
what happens when your exception gets extended? Are you sure you always want to log all instances, even from subclasses?
that static call will make proper unit testing much harder. You will have to mock away (using PowerMock(ito), bad idea) that static implementation.
it also makes other testing harder. What if there is a requirement at some point to simply instantiate such an exception object ... but without throwing it. Should an "unthrown" exception still be logged?! Or do you now need to go in and "un log" it?!
And really bad: you are in the process of creating an exception, because something failed. Now assume: you have a bug somewhere in that logging code. That only kicks in "randomly". What happens now is: from time to time, your product runs into an exception (caused by X), but while trying to process that issue, you run into another exception. The potential result might be that you lose the information about X happening. Thing is: error handling should be simple and straight forward. Behind the covers logging of exceptions from constructors is not a good idea.
The idea of exceptions is:
- they are created and thrown
- they are caught and "processed".
Such kind of logging belongs into that "processing" part. The component that catches these exceptions may gleefully invoke that static method, but not the exception itself.
The responsibility of the exception is to provide information about that fail. It is not its responsibility to do parts of the required error handling!
You can create your own abstract class which extends exception, call utility method from its constructor(s) and make the Implementation classes extend it, e.g.:
public abstract class BaseException extends Exception {
public BaseException(Throwable t) {
super(t);
ExceptionUtil.logExceptionToElasticSearchServer(t);
}
//Other constructors
}
Once done, your impl class would look like this:
public class MyException extends BaseException {
private static final long serialVersionUID = 1L;
public MyException() {
super();
}
public MyException(final Throwable e) {
super(e);
}
public MyException(final String message) {
super(message);
}
public MyException(final String message, final Throwable e) {
super(message, e);
}
}
Given the following code:
interface Provider
{
String getStuff();
}
class CustomProvider implements Provider
{
public String getStuff() throws RuntimeException
{
// possibly throwing an exception
return "some stuff";
}
}
class Main
{
public static void main(String[] args)
{
Main main = new Main();
main.test(new CustomProvider());
}
public void test(Provider provider)
{
provider.getStuff(); // we don't know that this can throw an exception!
}
}
In this particular case we know it but may not in another situation.
How can we protect from the situation where an implementation of an interface throws an unchecked exception but the client method doesn't know the specific implementation of the interface?
It seems that sometimes with unchecked exceptions you can actually never know if calling a method can throw an exception or not.
A solution could be change the signature of the method in the interface:
interface Provider
{
String getStuff() throws Exception;
}
This will ensure that the clients of that method will be advised that an exception can be thrown in all implementations. The problem with this is that maybe none of the implementations of the interface will actually throw an exception. Also putting a "throws Exception" in each method of an interface looks a bit weird.
It seems that sometimes with unchecked exceptions you can actually never know if calling a method can throw an exception or not.
The compiler doesn't check unchecked exceptions. You can document the constraints of the interface, but they won't be automatically validated by the compiler.
You suggest declaring that the method throws Exception. A more constrained approach would be to declare that the method throws some checked exception.
For example, you could declare specifically that your method may throw an I/O exception, as shown below. Callers then need only handle or throw IOException, rather than many more possible Exceptions.
interface Provider
{
String getStuff() throws IOException;
}
Another option is to declare an ad hoc exception type. This allows the interface to advertise an exception contract with callers, without limiting what kinds of exceptions implementations can encounter.
interface Provider
{
String getStuff() throws ProviderException;
}
class MyProvider implements Provider {
public String getStuff() throws ProviderException {
try {
...
} catch ( IOException e ) {
throw new ProviderException( e );
}
}
}
public class ProviderException extends Exception {
public ProviderException( Exception cause ) {
super( cause );
}
...
}
when coding. try to solve the puzzle:
how to design the class/methods when InputStreamDigestComputor throw IOException?
It seems we can't use this degisn structure due to the template method throw exception but overrided method not throw it. but if change the overrided method to throw it, will cause other subclass both throw it.
So can any good suggestion for this case?
abstract class DigestComputor{
String compute(DigestAlgorithm algorithm){
MessageDigest instance;
try {
instance = MessageDigest.getInstance(algorithm.toString());
updateMessageDigest(instance);
return hex(instance.digest());
} catch (NoSuchAlgorithmException e) {
LOG.error(e.getMessage(), e);
throw new UnsupportedOperationException(e.getMessage(), e);
}
}
abstract void updateMessageDigest(MessageDigest instance);
}
class ByteBufferDigestComputor extends DigestComputor{
private final ByteBuffer byteBuffer;
public ByteBufferDigestComputor(ByteBuffer byteBuffer) {
super();
this.byteBuffer = byteBuffer;
}
#Override
void updateMessageDigest(MessageDigest instance) {
instance.update(byteBuffer);
}
}
class InputStreamDigestComputor extends DigestComputor{
// this place has error. due to exception. if I change the overrided method to throw it. evey caller will handle the exception. but
#Override
void updateMessageDigest(MessageDigest instance) {
throw new IOException();
}
}
In this case, your super class is not meant to throw an exception.
This is a case where your subclass is thus throwing an exception which is not expected by the overlying software architecture. Thus you can :
update all subclasses to throw exceptions.
wrap the entire Digestor class framework in a new class system.
(simplest) maintain the current code and simply wrap any exceptions you wish to throw in a RuntimeException.
RuntimeExceptions are the idiomatic way to throw exceptions in java which are not checked by the compiler or by method signatures, which occur somewhat unexpectedly.
Your requirements are schizophrenic.
You've got to decide whether the DigestComputor.updateMessageDigest method can, or can not throw IOException. If you want that to be possible, then you must add it to the signature in the base class. That is the only way to force the caller to do something about an IOException. But the downside is that you also force callers of the other subclasses to handle the IOException ... which won't occur.
You cannot create a method override that throws checked exceptions that the overridden method does not. That would break subtype substitutability, and Java doesn't allow it.
It it like a fork in the road. You have to decide to go one way or the other. You can't go both ways at the same time.
However there is a compromise (sort of):
public abstract class Base {
public abstract void method() throws IOException;
}
public class A extends Base {
public void method() throws IOException {
//
}
}
public class B extends Base {
public void method() { // Doesn't throw!!!
//
}
}
Now, if the caller knows that it has an instance of B it can do something like this:
Base base = ...
B b = (B) base;
b.method(); // No need to catch or propagate IOException
(IIRC, the ability to do this ... i.e. to reduce the exceptions thrown in an overriding method ... was added in Java 1.5.)
As someone else suggested, the simplest thing to do would be to simple wrap the real exception in a runtime exception. As a result, you don't have to declare the exception in your throws clause. If you're ambitious enough you can make your own subclass of RuntimeException and catch it at a higher level (this is what hibernate does, it catches all SQLExceptions thrown and wraps them in some subclass of DataAccessException which is a runtime exception).
Suppose I have interface I and two classes A and B that implement it.
The implementation of method f of this interface in A throws one set of exceptions and the implementation in B throws another set. The only common ancestor of these exceptions is java.lang.Exception. Is it reasonable to declare f throwing java.lang.Exception in this case? Any other alternatives?
The reason why I am asking is that on the one hand java.lang.Exception seems too general to me and one the other hand listing all exceptions seems impractical considering possible other implementations.
Example:
interface I {
void f() throws Exception;
}
class A implements I {
public void f() throws IOException {}
}
class B implements I {
public void f() throws InterruptedException {}
}
The reason for using an interface is to abstract away the implementation details.
By throwing these exceptions, you're exposing implementation details that probably should be abstracted away.
Perhaps it would be best to define a new exception. Then each implementation of f() would catch the exceptions it knows about and throw the new exception instead so you'd have:
interface I {
void f() throws MyException;
}
class A implements I {
public void f() throws MyException {
try {
...
} catch (IOException e) {
throw new MyException(e);
}
}
}
class B implements I {
public void f() throws MyException {
try {
...
} catch (InterruptedException e) {
throw new MyException(e);
}
}
}
By wrapping the implementation exception, you're still exposing it to the caller and that can bite you when you're calling remote methods. In those cases you need to do more work to return useful information in a generic way.
Edit
There seems to be a bit of a dispute going on about the correct approach.
When we call f(), we'll need code like:
I instanceOfI = getI();
try {
instanceOfI.f();
}
catch ( /* What should go here ? */ )
It comes down to what is a good Exception class to put in the catch block.
With OP's original code we could catch Exception and then maybe try to see which subclass we have, or not depending on requirements. Or we could individually catch each subclass but then we'd have to add catch blocks when new implementations throw different exceptions.
If we used Runtime exceptions it would come to much the same thing except that we could alternatively defer the exception handling to a caller method without even giving the possibility of exceptions any thought.
If we used my suggestion of using a new, wrapped exception then this means we have to catch MyException and then try to see what additional information is available. This essentially becomes very like just using an Exception, but requires extra work for the limited benefit of having a bespoke exception that can be tailored to the purpose.
This seems a bit backward. You should be throwing exceptions that are relevant and possibly specific to your interface, or not at all. Change the implementations to wrap a common Exception class (although not Exception itself). If you can't deal with this you may want to wrap the Exceptions in the implementations with a RuntimeException.
You could just declare the exceptions you throw
void f() throws IOException, InterruptedException;
If you use a decent IDE, it will correct this for you. I just throw the exception in the method, which the IDE gives the optionsto add to the method clause and its interface.
Let's say I have the following Java interface that I may not modify:
public interface MyInterface {
public void doSomething();
}
And now the class implementing it is like this:
class MyImplementation implements MyInterface {
public void doSomething() {
try {
// read file
} catch (IOException e) {
// what to do?
}
}
}
I can't recover from not reading the file.
A subclass of RuntimeException can clearly help me, but I'm not sure if it's the right thing to do: the problem is that that exception would then not be documented in the class and a user of the class would possibly get that exception an know nothing about solving this.
What can I do?
We all agree: the interface is faulty.
Solution I chose
I finally decided to write a MyVeryOwnInterface that extends MyInterface and adds as part of the signature of the faulty methods the MyRuntimeException:
public interface MyVeryOwnInterface extends MyInterface {
public void doSomething() throws MyRuntimeException;
}
class MyImplementation implements MyVeryOwnInterface {
public void doSomething() throws MyRuntimeException {
try {
// read file
} catch (IOException e) {
throw new MyRuntimeException("Could not read the file", e);
}
}
}
You've encountered the problem of leaky abstractions. There is no really good solution, and using a RuntimeException pretty much the only thing you can do.
Arguably, this is also an example for why checked exceptions are a failed concept.
I'd throw a new IOError(e); and file an issue at the maintainer of the interface.
If you can't recover than you need to throw and thus wrap it into a RuntimeException or an Error and throw that.
public class Unchecked extends Error {
private final Exception source;
public Unchecked( Exception source) {
this.source = source;
}
public String toString() {
return "Unchecked Exception, Caused by: " + source;
}
public Exception getSource() {
return source;
}
public static Unchecked wrap( Exception cause ) {
return new Unchecked(cause);
}
}
Clearly the interface designer is at fault for not considering the possibility that doSomething() may fail. Ideally he should have either allowed IOException to be thrown (if he suspected that IO wouldbe invovled) or a SomethingException (checked) which you could use to wrap your IOException.
If the interface designer is available to you, talk to them and ask what they expected to happen in the case of failure. Maybe they can change the interface: or maybe it is acceptable to fail silently according to the interface's contract.
Failing all of these you are reduced to a choice of failing silently (possibly recording but not responding to the problem) or throwing a RuntimeException which may terminate the process.
I don't think there is anything to do except to declare throws IOException in the interface.
That is simply the nature of Java interfaces and checked exceptions.
You could have another method in your class (doSomethingDangerous) that throws the IOException. From the doSomething-implementation, you simply call doSomethingDangerous (wrapped in a try/catch) and then where ever you wish to be careful about doingSomething you call doSomethingDangerous directly.
I would suggest
throw new RuntimeException("while reading file " + fileName + "...", e);
Isn't the problem here, that the interface does not expect any problems at all?
(and you may want to create your own OurCompanyDomainException extends RuntimeException to make it easy to distinguish in the code on the other side of the interface).