Showing posts with label exception. Show all posts
Showing posts with label exception. Show all posts

Thursday, 1 October 2015

Calling super constructors

So, a constructor in a subclass, if it needs to call the constructor in the super class, is required to do this in the first line of the body of the constructor1.

If it does not, Java will insert a call to the default super constructor. If it does not exist, you get a compile time error.

So, what if you need to do things, before the super call takes place?

As the object is in the process of being constructed (that's why it's called a constructor), the object is in a non-valid state. This likely explains why the language designers felt that a call to another constructor should be the first part of the body of a constructor.

Well, apparently the only solution is to do everything you need inside the expressions that take the place of the super constructor arguments.

I was forced to do just that in my MudWebException.

So, there's an easy workaround, but it feels clumsy.

Take care not to access any of the methods or properties of the object that is being constructed, as it is in a non-valid state. As a matter of fact, I think it's a really bad idea to call methods in the object from within your constructor.

References

[1] JLS 8.0 Section 8.8.7. Constructor Body
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#d5e14100
StackOverflow - Why does this and super have to be the first statement in a constructor?
http://stackoverflow.com/questions/1168345/why-does-this-and-super-have-to-be-the-first-statement-in-a-constructor

Friday, 28 August 2015

Testing for Exceptions

The old way

There are a few ways of testing for exceptions. The old way was to just catch the exception and then do any asserts that you need. See below:

Advantages:
  • you can do anything you like
Disadvantages:
  • boilerplate takes up a large part
  • errorprone, for example forgetting to add the fail, means the testcase will pass if there's no exception.

TestNG

TestNG provides an extention to the @Test annotation that checks for exceptions. In the example below, it is even possible to check that the appropriate exception message is returned (using a regular expression).

Advantages:
  • it is immediately clear that the test tests an error case
Disadvantages:
  • not possible to do any checks or asserts after the exception is thrown
I did have a discussion with a colleague of mine, regarding the fact that I wished to verify data as well as exceptions.

His argument is, if your test is both verifying data as well as exceptions, you could pull these two apart into two separate tests. One test that tests for the exception, and one test that verifies the data. I countered that, as in his case, both tests verify the exact same behaviour in the SUT (System Under Test), it should be one test. Let me know what your opinions are.

JUnit

JUnit, in the new version (since 4.7), has an additional solution based on mocking stuff:

Advantages:
  • asserts after the exception is thrown become possible
  • you can do anything you like
Disadvantages:
  • a little boilerplate
  • not immediately clear that it's an exceptional testcase
  • I don't much like mocking

References

StackOverflow - JUnit Testing Exceptions
http://stackoverflow.com/questions/15216438/junit-testing-exceptions
StackOverflow - JUnit test analysing expected exceptions
http://stackoverflow.com/questions/4489801/junit-test-analysing-expected-exceptions

Thursday, 16 July 2015

Disappearing Exceptions

Quoting from [1]:
If the catch block completes abruptly for reason R, then the finally block is executed. Then there is a choice:

If the finally block completes normally, then the try statement completes abruptly for reason R.

If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
(Emphasis mine)

Conclusion

It is unwise to NOT catch Exceptions or throw Exceptions in a Finally block. An exception that is thrown in the finally block, may cause an exception in the try to be discarded. This can lead to errors that obscure the original error.

I can imagine how easy this can happen, for example, if there is an Exception in the try in such a fashion that the closing of resources in the Finally clause will also throw an Exception.

In fact, that is what happened at work, and threw me for a loop when attempting to debug.

Addendum

Luckily, with Java 72, when using the try-with-resources statement, this problem belongs to the past. Of course this only belongs to the past, if your try-catch-finally can be replaced with a try-with-resources.

To be specific, when using try-with-resources only the exception in the try is thrown. Subsequent exceptions, caused by the closing of the resources, are suppressed. But even these exceptions can still be recovered, by requesting all suppressed exceptions from the exception thrown in the try block3.

(Addendum added: 23 july 2015)

References

[1] JLS - 14.20.2. Execution of try-finally and try-catch-finally
http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2
[2] The Java™ Tutorials - The try-with-resources Statement
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
[3] JavaDoc - Throwable.getSupressed()
http://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#getSuppressed--