Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Thumbs up for suppressable exceptions in JDK 1.7

12 views
Skip to first unread message

Jan Burse

unread,
Sep 27, 2011, 3:31:03 AM9/27/11
to
Dear All

Was just playing around with suppressable exceptions
in JDK 1.7. This looks like a great improvement for
bug hunting!

Best Regards

Manually Suppressed:
------------------

public class TestSuppressed {

public static void main(String[] args) throws Exception {
try {
throw new IllegalArgumentException("x");
} catch (IllegalArgumentException x) {
x.addSuppressed(new IllegalArgumentException("y"));
throw x;
}
}

}

gives:

Exception in thread "main" java.lang.IllegalArgumentException: x
at TestSuppressed.main(TestSuppressed.java:12)
Suppressed: java.lang.IllegalArgumentException: y
at TestSuppressed.main(TestSuppressed.java:14)
... 5 more

Automatically Suppressed:
---------------------

public class TestSuppressed implements AutoCloseable {

public static void main(String[] args) throws Exception {
try (TestSuppressed ts=new TestSuppressed()) {
throw new IllegalArgumentException("x");
}
}

public void close() throws Exception {
throw new IllegalArgumentException("y");
}

}

gives:

Exception in thread "main" java.lang.IllegalArgumentException: x
at TestSuppressed.main(TestSuppressed.java:9)
Suppressed: java.lang.IllegalArgumentException: y
at TestSuppressed.close(TestSuppressed.java:20)
at TestSuppressed.main(TestSuppressed.java:10)
... 5 more

Roedy Green

unread,
Sep 27, 2011, 5:28:30 AM9/27/11
to
On Tue, 27 Sep 2011 09:31:03 +0200, Jan Burse <janb...@fastmail.fm>
wrote, quoted or indirectly quoted someone who said :
I think you need some exposition on why this is a good thing.
--
Roedy Green Canadian Mind Products
http://mindprod.com
It should not be considered an error when the user starts something
already started or stops something already stopped. This applies
to browsers, services, editors... It is inexcusable to
punish the user by requiring some elaborate sequence to atone,
e.g. open the task editor, find and kill some processes.

Jan Burse

unread,
Sep 27, 2011, 5:38:44 AM9/27/11
to
Roedy Green schrieb:

> I think you need some exposition on why this is a good thing.

Its a good think for hunting down bugs. You don't
have to sift through some logs written in the finally
clause of some try/catch, you can even spare this code.

But instead you get all layed out in front of you in
the exceptions catched in the toplevel of your application.
Or eventually written from there to some log.

Agreed?

Best Regards

Tom Anderson

unread,
Sep 27, 2011, 3:43:03 PM9/27/11
to
On Tue, 27 Sep 2011, Roedy Green wrote:

> On Tue, 27 Sep 2011 09:31:03 +0200, Jan Burse <janb...@fastmail.fm>
> wrote, quoted or indirectly quoted someone who said :
>
>> Was just playing around with suppressable exceptions in JDK 1.7. This
>> looks like a great improvement for bug hunting!
>> ... 5 more
>
> I think you need some exposition on why this is a good thing.

It avoids this common mistake:

try {
doSomethingWhichMightThrowAnException();
}
finally {
doSomeCleanupWhichMightThrowAnException();
}

In that code, if both methods throw an exception, you will only see the
second. The first exception - the one which actually caused the problem -
will be lost. It's as if the VM has a very short attention span, and can
only focus on whatever exception was most recently thrown.

In Java 7, you can put the cleanup into the close() method of an
(Auto)Closeable, and use the try-with-resources form:

class Thing implements AutoCloseable {
public void close() throws AnException {
doSomeCleanupWhichMightThrowAnException();
}
}

try (Thing t = new Thing()) {
doSomethingWhichMightThrowAnException();
}

There, the compiler will arrange things so that if close() does throw an
exception, it will be 'suppressed', and tagged on to the exception coming
from doSomethingWhichMightThrowAnException() as a suppressed exception.

tom

--
We discovered in Nature's work a pattern of sloppiness, indifference to
basic scholarly standards, and flagrant errors so numerous they completely
invalidated the results. -- Encyclopaedia Britannica

Daniele Futtorovic

unread,
Sep 29, 2011, 12:05:09 PM9/29/11
to
Indeed, but even more generally, we can from now on register
"suppressed" exceptions ourselves, as Jan's code and the JSE7 Javadoc
for java.lang.Throwable show. Great Thing IMHO. Closes a hole that's
been lurking there for a very long time.

Thanks Jan for bringing this to my attention.

--
DF.
Determinism trumps correctness.

Daniel Pitts

unread,
Sep 29, 2011, 2:25:57 PM9/29/11
to
This will definitely be a big help debugging issues. It may also help
fill up log files faster ;-). I can see it being extremely useful in a
try/catch/retry scenario (such as a service which tries a few times to
connect to a remote machine, and gets a different error each time).

I want to read up on it, but I wonder if it will help with this
(unfortunate) situation:

try {
buggyCodeThrowsNullPointerException();
} catch (Exception oopsThisWasIgnoredByLazyProgrammer) {
throw new BusinessLayerSpecificException(
"Unable to process request for no good reason.");
}

This suppresses a bug, but the original programmer wasn't thinking about
potential bugs, only recoverable exceptions. The exception is
effectively suppressed.

Arved Sandstrom

unread,
Sep 29, 2011, 5:57:30 PM9/29/11
to
On 11-09-29 01:05 PM, Daniele Futtorovic wrote:
[ Useful info snipped ]
>
> Indeed, but even more generally, we can from now on register
> "suppressed" exceptions ourselves, as Jan's code and the JSE7 Javadoc
> for java.lang.Throwable show. Great Thing IMHO. Closes a hole that's
> been lurking there for a very long time.
>
> Thanks Jan for bringing this to my attention.
>
Indeed, I second that sentiment. I had missed this interesting bit of
information.

AHS
--
I tend to watch a little TV... Court TV, once in a while. Some of the
cases I get interested in.
-- O. J. Simpson

Daniele Futtorovic

unread,
Sep 29, 2011, 5:57:06 PM9/29/11
to
On 29/09/2011 20:25, Daniel Pitts allegedly wrote:
> I want to read up on it, but I wonder if it will help with this
> (unfortunate) situation:
>
> try {
> buggyCodeThrowsNullPointerException();
> } catch (Exception oopsThisWasIgnoredByLazyProgrammer) {
> throw new BusinessLayerSpecificException(
> "Unable to process request for no good reason.");
> }
>
> This suppresses a bug, but the original programmer wasn't thinking about
> potential bugs, only recoverable exceptions. The exception is
> effectively suppressed.

Probably won't help that situation.

The suppressed exception mechanism addresses a structural short-coming
of the Java core libraries. If at any point you were confronted with two
Throwables (and their respective stack of causes), and planned to throw
something, you had no choice but to decide to drop one of the two.

The situation you're describing here is not a structural problem, it's
bad code. Language changes can sometimes facilitate good code or the
opposite, but they're not a solution to bad code. The only guaranteed
safeguard against bad coding is not coding at all.

In other words, while the structural problem could be addressed by a
change in the language/libraries, I don't think the one of bad code can.

Jan Burse

unread,
Sep 30, 2011, 5:30:41 AM9/30/11
to
Daniel Pitts schrieb:
> I want to read up on it, but I wonder if it will help with this
> (unfortunate) situation:
>
> try {
> buggyCodeThrowsNullPointerException();
> } catch (Exception oopsThisWasIgnoredByLazyProgrammer) {
> throw new BusinessLayerSpecificException(
> "Unable to process request for no good reason.");
> }

I would eventually do the following:

try {
buggyCodeThrowsNullPointerException();
} catch (Exception oopsThisWasIgnoredByLazyProgrammer) {
throw new BusinessLayerSpecificException(
"Unable to process request for no good reason.",
oopsThisWasIgnoredByLazyProgrammer);
}

So use the cause of an exception for piggybacking
the reason. This is a kind of a competing mechanism
to supression.

Bye

Jan Burse

unread,
Oct 2, 2011, 7:38:21 AM10/2/11
to
Jan Burse schrieb:
> Dear All
>
> Was just playing around with suppressable exceptions
> in JDK 1.7. This looks like a great improvement for
> bug hunting!
>
> Best Regards

Just see that java.sql.Statement implements AutoClosable
in JDK 1.7. Is this also worth a thumbs up?

Unfortunately not yet. If I am using some java database
object cursors, then I typically have some database
beans as follows:

class Bean() {
void open();
boolean next();
void close();
}

Then I have to wait until my DBBean also implements
the AutoClosable interface. As I cannot use the
try-with-resource statement. Since the SQL statement
is burried in the Bean.

Any other interesting classes that have received the
AutoCloseable interface in JDK 1.7? My IDE says that
around ~580 classes/interfaces implemented/extend
this interface!

Bye

Jan Burse

unread,
Oct 2, 2011, 7:45:36 AM10/2/11
to
Jan Burse schrieb:
>
> Any other interesting classes that have received the
> AutoCloseable interface in JDK 1.7? My IDE says that
> around ~580 classes/interfaces implemented/extend
> this interface!

Ok the number is so high, because in JDK 1.7 Closeable
extendes AutoCloseable. But we find classes such as

javax.sound.midi.Receiver
javax.sound.midi.MidiDevice
javax.sound.midi.Transmitter
javax.sound.sampled.Line
javax.sql.ResultSet
javax.sql.Connection

Which are genuine AutoClosable.

Bye


Tom Anderson

unread,
Oct 3, 2011, 2:08:14 PM10/3/11
to
I believe that they automatically added AutoCloseable to every class or
interface with a no-args close() method. That's quite a few.

tom

--
Now I am thoroughly confused. -- Colin Brace sums up RT3090 support
in Linux
0 new messages