How do YOU handle Exceptions?

78 views
Skip to first unread message

Hannu Leinonen

unread,
Aug 14, 2009, 8:31:49 PM8/14/09
to java...@googlegroups.com
Hello posse (of The Posse)!


I've been lately discussing about exception handling in Java with my
workmates. And I've noticed that there's some uncertainty about
Exceptions and how to use them. Currently we're working on a quite
traditional three-tier Spring+Hibernate web app (using way too much of
that disgusting null programming, but that's another story).

Personally I usually regard ... catch (Exception e) ... as a code smell
because it will catch - usually unintentionally - all RuntimeExceptions
too. Not to mention catching Throwable, like there was a lot we could do
with Errors. My current style is catching all checked exceptions on
their own blocks and catching RuntimeException on it's own block where
it makes sense (at least in controllers). But that sometimes makes the
code ugly with a dozen catch blocks doing exactly the same thing. AFAIK
Project Coin is going to fix this annoyance. Would it be better in a
situation where I anyways catch RuntimeException to use Exception as it
is the lowest common denominator?

How do you make the most out of your Exceptions? And how do you do it in
multi-tier architecture?


Best Regards,
Hannu

Casper Bang

unread,
Aug 14, 2009, 8:56:43 PM8/14/09
to The Java Posse
Are aware of the seminal book "Effective Java" by Joshua Bloch which
devotes an entire chapter to Java exceptions?

/Casper

Hannu Leinonen

unread,
Aug 14, 2009, 9:05:03 PM8/14/09
to java...@googlegroups.com
Sure, working on reading it. For some reason I haven't read the
Exception chapter yet, but I'll take that one next. Thanks for the
suggestion!

Eventhough I think at least some of my workmates have read that book,
still they don't seem to have that clear view about exceptions.


-Hannu

Christian Catchpole

unread,
Aug 15, 2009, 5:04:43 AM8/15/09
to The Java Posse
Handle them? I have them serialized and jettisoned into space. One
day an alien race will visit us and communicate with the
NullPointerException.

Andreas Petersson

unread,
Aug 15, 2009, 5:11:10 AM8/15/09
to java...@googlegroups.com
We did a quite large code refactoring regarding Exceptions in my company
some weeks ago.
The codebase is about 2k classes. Before we did the refactoring, we had
a pretty harmful way of dealing exceptions, like this:

//do not try this at home...
try{
Connection c = getConn();
query_data();
do_resource_cleanup();
return result;
}catch (SqlException e){
logger.info("hmm i guess this just failed");
return "";
}

code like this was cluttered all over the source. what happened was that
people using the system thought their updates were successful, when in
fact they were not.
also, we leaked tons of connections and preparedstatements.

we changed everything to a catch-rethrow as RuntimeException pattern. a
central Servlet filter catches all exceptions,loggs errors to file and
mail, and redirects to a "submit error description" page.

so the code mostly looks like this now:

Connection c = null;
try{
c = getConn();
return query_data();
}catch (SqlException e){
throw new MyRuntimeException("unexpected error calling XXX using
parameters : PPPP " ,e);
}finally{
do_resource_cleanup(); //check for nulls
}

this is how it looks like the old jdbc-based data access classes, which
are the majority. the hibernate-based data access classes swallowed
runtimeexceptions, their erronous error handling code was entirely
removed, cutting their code footprint to 1/3, most of the methods are
one-liners now.

this refactoring affected about 500 classes. most of the work was done
using the excellent Structural Search and Replace tool inside IntelliJ
Idea. prototyping the changes took about 2 days the actual replace was
done in a couple of minutes after we knew what to change.

Viktor Klang

unread,
Aug 15, 2009, 5:25:41 AM8/15/09
to java...@googlegroups.com
final class Utils
{
   public final static RuntimeException woBoilerplate(Exception e)
   {
        return (e instanceof RuntimeException) ? (RuntimeException)e : new RuntimeException(e);
   }
}


...

import static Utils.unchecked;


try
{
  doStuff();
}
catch(Exception e)
{
    throw woBoilerplate(e);
}
finally
{
  cleanup();
--
Viktor Klang

Rogue Scala-head

Blog: klangism.blogspot.com
Twttr: viktorklang

Fabrizio Giudici

unread,
Aug 15, 2009, 5:42:06 AM8/15/09
to java...@googlegroups.com
Viktor Klang wrote:
> final class Utils
> {
> public final static RuntimeException woBoilerplate(Exception e)
> {
> return (e instanceof RuntimeException) ? (RuntimeException)e :
> new RuntimeException(e);
> }
> }
>
>
For me, similar to Victor and Andreas, with the exception that part of
my rethrown are checked exceptions ;-)

--
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
weblogs.java.net/blog/fabriziogiudici - www.tidalwave.it/blog
Fabrizio...@tidalwave.it - mobile: +39 348.150.6941

Jeff Grigg

unread,
Aug 15, 2009, 8:56:17 AM8/15/09
to The Java Posse
I like the beauty and simplicity of completely empty catch blocks. >;-
> OK, some developers, to comply with corporate documentation
standards, put comments there. >;->


(Reality is that I'll usually wrap checked exceptions in
RuntimeExceptions at a low level, and then catch Exception at the top
level -- to log it and abort or retry the transaction or user action.
There's a lot of really bad code out there that misuses exceptions and
does exception handling cleanup wrong. It's a problem!!)

Casper Bang

unread,
Aug 15, 2009, 9:50:35 AM8/15/09
to The Java Posse
Hehe that's a big can of worms to open up in here, but I do the same.

/Casper

Fabrizio Giudici

unread,
Aug 15, 2009, 11:22:50 AM8/15/09
to java...@googlegroups.com
Casper Bang wrote:
> Hehe that's a big can of worms to open up in here, but I do the same.
>
I too have some rough code that does exception handling for
transactions, to decide whether to retry or abort.

Reinier Zwitserloot

unread,
Aug 15, 2009, 2:42:43 PM8/15/09
to The Java Posse
I'll one up y'all:

public class Sneak {
public static RuntimeException sneakyThrow(Throwable t) {
if ( t == null ) throw new NullPointerException("t");
Sneak.<RuntimeException>sneakyThrow0(t);
return null;
}

@SuppressWarnings("unchecked")
private static <T extends Throwable> void sneakyThrow0(Throwable t)
throws T {
throw (T)t;
}


There is absolutely no point in wrapping everything into a gazillion
layers of exceptions - that just results in 10 pages of stacktrace to
walk through. Preferably, all your classes throw the exceptions they
cause, but if interface restrictions are preventing you from sticking
'throws SQLException' in the appropriate places, use this. Don't wrap
unless there's a good reason for it. A good reason would be if e.g. a
database abstraction layer has its own 'DataSourceException', and a
specific implementation that works with files wraps
FileNotFoundExceptions in DataSourceExceptions. That's useful
wrapping. turning everything into 'MyRuntimeException' is a waste of
time.


Or, of course, use project lombok and add "@SneakyThrows
(SQLException.class)" to your method, which saves you a try/catch
block.


On Aug 15, 5:22 pm, Fabrizio Giudici <fabrizio.giud...@tidalwave.it>
wrote:
> Fabrizio.Giud...@tidalwave.it - mobile: +39 348.150.6941

Peter Becker

unread,
Aug 16, 2009, 8:24:14 PM8/16/09
to java...@googlegroups.com
I'm mostly in the rethrow-as-checked camp.

One note: while I tend to consider a catch(Exception) to be a major
no-no, I believe a catch(Throwable) can be useful sometimes. As example:
I maintain a little indexing tool based on Lucene, and when indexing a
document I tend to do a catch(Throwable): the indexing tools sometimes
fail and the only thing I want to do is to log and continue. In every
case where there is a separate task running whose failure is not
critical to the rest of the system, catch(Throwable) seems right to me.
You want to include the dreaded OutOfMemoryError, so don't catch Exception.

Of course you still can't rely on being safe this way -- the
OutOfMemoryError can hit other parts of the code and I actually had a
library call System.exit(..) on me.

I guess the totally right thing would be spawning a new process, but
that's just too expensive. Catching Throwable seems a reasonable
compromise. But of course only if your system is not too critical to
begin with.

Peter

Jess Holle

unread,
Aug 16, 2009, 10:04:06 PM8/16/09
to java...@googlegroups.com
The only valid thing I know of upon an OutOfMemoryError is to do a log and do a System.exit().  Why?  Much like any other VirtualMachineError, this can occur between any 2 lines of code anywhere -- and no one writes enough compensating code to handle this properly.  Thus if you have any shared state between threads, which you almost certainly do in reality, you have to euthanize the JVM -- unless you are feeling lucky and just want to bet no shared data got corrupted.

Peter Becker

unread,
Aug 16, 2009, 10:58:42 PM8/16/09
to java...@googlegroups.com
While I agree that you can have shared state, the scenario I had was a
clean worker: some data goes in before the thread gets started, other
data comes out at the end.

System.exit is a bad idea generally since you don't really know who is
going to use your code in the future. If you call System.exit in your
average Tomcat installation you'll probably take it down with you. I
tend to restrict the System.exit calls to main(..) methods.

I don't think there is one answer to this problem, but depending on what
kind of application you are writing the compromises might look
different. I still stand to the decision of catching Throwable in that
particular case and I have seen quite a few OutOfMemoryErrors during
indexing that the tool survived. Also the odd StackOverflowError. In all
these cases I much preferred the log&continue approach and while I know
it could go wrong it hasn't failed me so far. If the application ever
crashes badly it won't hurt anyone -- your average user is much too used
to restarting programs anyway :-)

Peter

Reinier Zwitserloot

unread,
Aug 17, 2009, 3:01:56 AM8/17/09
to The Java Posse
Anytime you have a framework that calls upon a hook kind of deal to do
something, catching Throwable is warranted.

A servlet container should wrap the call to the doGet method in catch
Throwable.

Thread should call its Runnable.run() via catch Throwable.

The thing is that most APIs that qualify actually do catch Throwable,
but they don't add 'throws Throwable' to the matching interface. This
drives me NUTS. It's utter API design fail when you don't think this
through. the servlet API screwed this up, and so did
java.lang.Runnable. Argh!

ant can run java code in-process. It actually installs a security
manager that allows everything EXCEPT System.exit(), to avoid that
issue of code just shutting down ant's process by calling System.exit.
It's a rather blunt solution, but it does work. Your rule of thumb is
a good one: Only call System.exit() inside main. (if java were to be
redesigned, System.exit() should probably go away, and the function of
providing a return value should be accomplished via letting the main()
method return an int).

Jess Holle

unread,
Aug 17, 2009, 7:23:09 AM8/17/09
to java...@googlegroups.com
Peter Becker wrote:
> While I agree that you can have shared state, the scenario I had was a
> clean worker: some data goes in before the thread gets started, other
> data comes out at the end.
>
> System.exit is a bad idea generally since you don't really know who is
> going to use your code in the future. If you call System.exit in your
> average Tomcat installation you'll probably take it down with you. I
> tend to restrict the System.exit calls to main(..) methods.
>
Low-level code shouldn't be catching VirtualMachineError -- it should
always re-throw it.

Only top-level thread handlers should catch these errors and call
System.exit().


> I don't think there is one answer to this problem, but depending on what
> kind of application you are writing the compromises might look
> different. I still stand to the decision of catching Throwable in that
> particular case and I have seen quite a few OutOfMemoryErrors during
> indexing that the tool survived. Also the odd StackOverflowError. In all
> these cases I much preferred the log&continue approach and while I know
> it could go wrong it hasn't failed me so far. If the application ever
> crashes badly it won't hurt anyone -- your average user is much too used
> to restarting programs anyway :-)
>

If you have no shared state or do not mind it potentially being corrupt,
then sure keep plugging along as best you can.

--
Jess Holle

Peter Becker

unread,
Aug 17, 2009, 5:11:27 PM8/17/09
to java...@googlegroups.com
Jess Holle wrote:
> Peter Becker wrote:
>
>> While I agree that you can have shared state, the scenario I had was a
>> clean worker: some data goes in before the thread gets started, other
>> data comes out at the end.
>>
>> System.exit is a bad idea generally since you don't really know who is
>> going to use your code in the future. If you call System.exit in your
>> average Tomcat installation you'll probably take it down with you. I
>> tend to restrict the System.exit calls to main(..) methods.
>>
>>
> Low-level code shouldn't be catching VirtualMachineError -- it should
> always re-throw it.
>
I agree. But between the likelihood of this error being raised and the
damage done if you catch it when you shouldn't the risk seems quite
acceptable. Again: it is highly dependent on what your application is, I
would certainly not recommend this for a mission or even life critical
section of code.

> Only top-level thread handlers should catch these errors and call
> System.exit().
>

And what happens to other threads? If you call System.exit you should
have global knowledge of all application threads and their current
state. Even in the presence of a VirtualMachineError it is probably
better to try a clean shutdown. Calling System.exit could leave a lot of
things in inconsistent state that will be hard to recover from. Are all
your system's boundaries transactional?

Peter

Casper Bang

unread,
Aug 17, 2009, 6:58:40 PM8/17/09
to The Java Posse
For that we have Runtime().getRuntime().addShutdownHook() no? That's
what I used anyway with JSR-296, where Hans Muller had hardwired the
System.exit() call in the framework.

/Casper

Michael Neale

unread,
Aug 17, 2009, 8:47:54 PM8/17/09
to The Java Posse
The only sane way is this:

try {

.. your code here

} catch (Throwable t) {
for (int i =0; i< 1000; i++)
java.awt.Toolkit.beep();
System.exit(-1);
}

Sometimes can use a Runtime.exec to delete the home directory for good
measure, but that means platform specific code.

phil swenson

unread,
Aug 17, 2009, 9:29:39 PM8/17/09
to The Java Posse
I'm happy to see all the runtime exception advocates on here.
Definitely not the mainstream view. Smart crowd :)

I would love to see some example of how you guys write JDBC code.
JDBC code is usually the most heinous of all with all the SQLException
and resource handling crap you have to do.

Please post a snippet :)

Christian Catchpole

unread,
Aug 17, 2009, 9:34:13 PM8/17/09
to The Java Posse
Go the "finally".. (there is that risk of the original exception
being lost and knock on ones cropping up)

PreparedStatement ps = connection.prepareStatement(sql);
try {
ResultSet resultSet = ps.executeQuery();
try {
while (resultSet.next()) {
// stuff
}
} finally {
resultSet.close();
}
} finally {
ps.close();
}

Christian Catchpole

unread,
Aug 17, 2009, 9:39:31 PM8/17/09
to The Java Posse
Ok, that's probably not what you were after....

On Aug 18, 11:34 am, Christian Catchpole <christ...@catchpole.net>
wrote:

Casper Bang

unread,
Aug 17, 2009, 10:03:39 PM8/17/09
to The Java Posse
You neglect to handle the checked exception declared by
prepareStatement no?

PreparedStatement stmt = null;
try{
stmt = connection.prepareStatement(sql);
final ResultSet rs = stmt.executeQuery();
try{
while (rs.next()){
// Stuff...
{
}
finally{
rs.close();
}
}
catch(SQLException e){
// Logging...
}
finally{
try{
stmt.close();
}
catch(SQLException whoTheFuckCares){
};
}

Really, how many other ways are there to do it I wonder now? (Apart
from wrapping certain things, like the last try-catch clause in some
general purpose "closer util"?).

/Casper

Josh Suereth

unread,
Aug 17, 2009, 10:22:05 PM8/17/09
to java...@googlegroups.com
+ 2000000000000

Now that you've reminded me of java.awt.Toolkit.beep();  havoc will be made!

Christian Catchpole

unread,
Aug 17, 2009, 10:55:35 PM8/17/09
to The Java Posse
No, i just let that go up. I really try to avoid the declare as null
then set thingy.

phil swenson

unread,
Aug 17, 2009, 10:57:16 PM8/17/09
to The Java Posse
you do it exactly the same way I do (well I do that and surround the
whole thing with a try{}catch(SQLException e){throw new
RuntimeException(e)}.
First time I've ever seen anyone else handle resource closing this
way.

Usually I see something like (this is mostly real code):

Connection conn = conManager.getConnection();
PreparedStatement updateStmt = null;
PreparedStatement deleteContainmentStmt = null;
PreparedStatement addContainmentStmt = null;
try {
updateStmt = conn.prepareStatement("UPDATE BLAH SET BLAH
= ?, BLAH2 = ? WHERE " +
"D = ?");
updateStmt.setFloat(1, safeWeight);
updateStmt.executeUpdate();
deleteContainmentStmt = conn.prepareStatement("DELETE FROM
BLAH = ?");
deleteContainmentStmt.setLong(1, blah.ID());
deleteContainmentStmt.executeUpdate();

final String insertSql = "INSERT INTO BLAH(BLAH_ID) VALUES
(?)";
addContainmentStmt = conn.prepareStatement(insertSql);
addContainmentStmt.setLong(1, 39393);
try {
addContainmentStmt.execute();
} catch (SQLException e) {
final StringBuilder msg = new StringBuilder();
msg.append("failed SQL [" + insertSql + "] ");
LoggingUtil.log(Storage.class, Level.DEBUG,
msg.toString(), e);
throw e;
}
}
} catch (SQLException e) {
conn.setLastException(e);
LoggingUtil.log(getClass(), Level.DEBUG, e.getMessage(),
e);
} finally {
if (updateStmt != null) {
try {
updateStmt.close();
} catch (SQLException e) {
LoggingUtil.log(getClass(), Level.DEBUG,
e.getMessage(), e);
}
}
if (deleteContainmentStmt != null) {
try {
deleteContainmentStmt.close();
} catch (SQLException e) {
LoggingUtil.log(getClass(), Level.DEBUG,
e.getMessage(), e);
}
}
if (addContainmentStmt != null) {
try {
addContainmentStmt.close();
} catch (SQLException e) {
LoggingUtil.log(getClass(), Level.DEBUG,
e.getMessage(), e);
}
}
conManager.freeConnection(conn);
}


On Aug 17, 7:34 pm, Christian Catchpole <christ...@catchpole.net>
wrote:

Christian Catchpole

unread,
Aug 17, 2009, 11:03:10 PM8/17/09
to The Java Posse
Wether you catch the other SQLException i guess depends on the
situation. I just find this very useful, wether it's SQL or
otherwise..

Thing thing = getThing();
try {
thing.use();
} finally {
thing.close();
}

There is no need to create Thing thing = null; outside the block then
null check it inside. The only gotchas are:

1. you might want to use a safeClose() to eat exceptions you dont want
overriding others
2. you can't insert any code between the Thing thing = getThing() and
the open of the try. Otherwise something in there could through and
you will miss the finally.

Michael Neale

unread,
Aug 17, 2009, 11:10:50 PM8/17/09
to The Java Posse
What do people think of the scala approach of no checked exceptions -
even checked exceptions are not treated specially by the constructor
(personally, I like it).



On Aug 18, 12:55 pm, Christian Catchpole <christ...@catchpole.net>
wrote:

Christian Catchpole

unread,
Aug 17, 2009, 11:14:59 PM8/17/09
to The Java Posse
Or again, serialize the Exceptions and jettison them into the sun...

http://twitpic.com/ebeci

Casper Bang

unread,
Aug 17, 2009, 11:24:27 PM8/17/09
to The Java Posse
Dangerous issue, but IMHO that's the way it should be. Any language
construct that derails you from your primary path of thinking is more
of a derailment than assistance. Tools are more than capable of
detecting and warning of alternative paths and lets face it, you're
going to need unit tests anyway. Fan also converts checked exceptions
into runtime exceptions for the same reason. In a sense, it's
staticness taken too far. Someone should short-circuit javac, since
checked exceptions really is just a figment of its imagination.

/Casper

phil swenson

unread,
Aug 17, 2009, 11:25:57 PM8/17/09
to The Java Posse
there is a reason no other language ever written has checked
exceptions - checked exceptions are a bad idea.

On my first java project back in 1999 I remember adding in a checked
exception to a utility class. It has effects on hundreds of classes
and 1000s of method calls. I then decided it was more trouble than it
was worth and switched everything to runtime exceptions. Worked
brilliantly.

Checked exceptions almost always degenerate into "throws exception" on
100s to 1000s of methods in your project. They simply don't scale,
one small change can ripple through an entire project. They also lead
to try{blahblah}catch(Exception e}{} (exception hiding). They lead to
logging the exception multiple times (catch, log, rethrow), giant
method signatures, exception wrapping, and other harmful practices.

The correct (IMO) way to handle it is to let the exception bubble up
to the top level thread and handle it there, whether it's present to
the user, log, and/or cancel a transaction. Exceptions almost never
can be recovered from and people are almost always fooling themselves
if they think they can. I think 95+% of the time exceptions are from
bugs, not from recoverable situations. People try to build hugely
fault tolerant systems and they end up hiding bugs.

In the rare case that you want to handle an exception at a lower
level, do it. But you certainly don't want this to be the default
behavior, it's the EXCEPTIONAL case. :)

phil swenson

unread,
Aug 17, 2009, 11:27:47 PM8/17/09
to The Java Posse
> Someone should short-circuit javac, since
> checked exceptions really is just a figment of its imagination.

I made this request on the Project Coin list and was very promptly
shot down. I really do wish someone would hack it into javac and have
and IDE switch to turn them off.

Christian Catchpole

unread,
Aug 18, 2009, 12:02:55 AM8/18/09
to The Java Posse
We've had many long threads on the checked vs unchecked debate. My
thought was that to take out checked exceptions was cheating and
simply avoiding an aspect of strong typing that was inconvenient. But
now I'm not so sure.

Reinier Zwitserloot

unread,
Aug 18, 2009, 3:00:23 AM8/18/09
to The Java Posse
public void handleWebRequest(String target, Request req, Response res)
throws Exception {
@Cleanup("release") Db db = worker.getDb();
db.doWhatever();
}



couldn't be simpler, really. @Cleanup is from project lombok, and it
ensures the db is released even if this method errors out. Note how I
just toss a 'throws Exception' on there. This is a servlet; it's
effectively an entire application all by itself. That kind of broad
context is allowed to throw whatever the heck it wants. The code that
calls into this code catches throwable, because if a servlet errors
out, even with something drastic like, say, an InternalError, it
should not take the whole webserver down with it. The code that
catches this does some sorting work on the exception in question, and
targets a different log file if it seems particularly nasty (such as
out of memory, internalerror, virtual machine error, and a few
others), but that's really an implementation detail. The point is: The
gazillion different instances of 'handleWebRequest' are as simple as I
could make them.

NB: The db object isn't passed in primarily because not all these
handlers need one, and the db engine is an entirely separate module,
so I'd rather avoid adding a dependency there. If I didn't have
lombok, I would make Db 'lazy' and grab a connection only when a
request happens, so that you don't have to try/finally this stuff, and
pass a Db object into the handleWebRequest call.

For you JDBC users, I suggest you go play with projectlombok.org.
Here's Christian Catchpole's code sample without lombok:

PreparedStatement ps = connection.prepareStatement(sql);
try {
ResultSet resultSet = ps.executeQuery();
try {
while (resultSet.next()) {
// stuff
}
} finally {
resultSet.close();
}
} finally {
ps.close();
}

and here's the same thing with lombok:

@Cleanup PreparedStatement ps = connection.prepareStatement
(sql);
@Cleanup ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
// stuff
}


If you have a need to handle SQLExceptions locally (I would like to
state again that if you are forced to do this, your framework sucks
and you should fix it!), it would turn into:

try {
@Cleanup PreparedStatement ps = connection.prepareStatement
(sql);
@Cleanup ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
// stuff
}
} catch ( SQLException e ) {
//What are ya gonna do now?
}


rule of thumb: If you can't do anything useful in your catch block
other than log and/or wrap it, you're doing it wrong.


And to the genius who mentioned beep(): Whoa. Did not know about it.
Evil! Muhahaha!

Reinier Zwitserloot

unread,
Aug 18, 2009, 3:00:25 AM8/18/09
to The Java Posse

Reinier Zwitserloot

unread,
Aug 18, 2009, 3:08:17 AM8/18/09
to The Java Posse

On Aug 18, 5:27 am, phil swenson <phil.swen...@gmail.com> wrote:
> > Someone should short-circuit javac, since
> > checked exceptions really is just a figment of its imagination.

Done, sort of, if you use eclipse, at any rate. Install project lombok
and stick:

@SneakyThrows

on every method that you have. You could also dive into the lombok
source code and change the SneakyThrows handler to just apply to every
method, even if it does not have that annotation. It would at least be
an interesting experiment to spend some time coding in plain java
except with checked exceptions just disabled wholesale. There's one
fairly major problem though: javac will not let you catch exceptions
unless a statement in the try block is known to throw that exception,
and with @SneakyThrows, that just doesn't happen anymore. I fervently
hope that this restriction is removed in java 7. It's somewhat likely;
Neal Gafter's idea of letting 'catch ( final Throwable t ) ' actually
have t only be all types that can legally be thrown by the statements
in the try block, so that you can do a general catch all and rethrow
without enumerating all types, has a rare condition in which old code
no longer compiles, which would be fixed if you indeed remove the
restriction that you can't catch exceptions that are never thrown in
the try block*. So, here's hopin' coin delivers.

*) Well, you can always catch a superclass or subclass of
RuntimeException and Error, but all the other ones, not so much.

NB: I discovered a bug in the sneaky throws code generator for
eclipse; every so often it'll make eclipse's parser get very confused
and you lose your syntax highlighting. It happens somewhat rarely, and
I don't have time today to figure out exactly what's causing it, but I
will get around to it at some point.

Peter Becker

unread,
Aug 18, 2009, 4:43:49 AM8/18/09
to java...@googlegroups.com
In Scala you get the Either type. That is superior for most cases where
one might use checked exceptions in Java.

I have used that style in Java, but you usually don't make friends with it.

Peter

Peter Becker

unread,
Aug 18, 2009, 6:13:54 AM8/18/09
to java...@googlegroups.com
I still believe that the main reason people hate checked exceptions is
that they have been used badly.

But I don't really like them either, I just dislike runtime exceptions
more ;-) The reason for that is that they hide things I might want to
know about when using an API. No one reads documentation well enough,
the enforcement checked exceptions give you is quite useful -- at least
given the context of Java. And I don't buy into the "just unit test"
argument, things like SQLException and IOException rarely happen in test
environments unless the test was designed to test just that -- it is the
exceptional case you don't expect that scares me.

What I would really like to see is a meet/or/disjunction/union operator
in the type system, with a case-like construct to resolve the resulting
types. Scala has two things that are halfway there (Either, case
classes), but neither is the full monty.

Peter

Reinier Zwitserloot

unread,
Aug 18, 2009, 6:43:36 AM8/18/09
to The Java Posse
Yes, an utopia with checked exceptions is probably pretty decent, but
as a practical matter they've been horribly abused. Not just by third
party libraries; the java core library is inconsistent in places and
has a lot of missing throws clauses in interfaces that can't be fixed
because it would break backwards compatibility. Trying to fix these
things is going to be even more painful than having to deal with
checked exceptions in the current circumstance, which is one of the
reasons why I advocate solving the problem directly. Such as offering
an opt out mechanism where a programmer can explicitly 'correct' the
compiler to say: Yah, I know, I know, this method call here DECLARES
that it'll throw SomeCheckedException, and I neither catch it nor
declare to throw it onwards, but, shaddap. I know what I'm doing, just
compile this code, and let me get on with my day.

It'll be abused, but the notion that exceptions will be abused in some
fashion is what we have to deal with. The question is: How can we make
sure the abuse is kept to a minimum? I'd assert that try {} catch
( Throwable t ) { Log.log(t); } is a much worse abuse than
sneakythrowing.

You get the benefit of being explicitly told about the checked
exceptions that you ought to be checking, but when the theory fails
due to a practical matter (the declared exception can't possibly
happen, or you want to throw the exception onward but due to a badly
designed interface you're not allowed to, etc, etc), you won't have to
jump through a bunch of hoops, obscuring the exception as you go.

Being able to return a disjoint type so you can cover extraordinary
exit conditions that way instead of throwing exceptions for them could
work, but I don't really know of any language that handles them all
that well. The only way I can see how it could possibly work is
pattern matching. Which scala can mostly do, can't it?

Viktor Klang

unread,
Aug 18, 2009, 6:48:31 AM8/18/09
to java...@googlegroups.com
The problem I feel is that an Exception should denote an EXCEPTIONAL occurrence, and be able to list all things that can happen is just plain impossible.
So switching to a fully checked exceptions would mean that every method signature should mandatory include stuff like:

public void foo(Bar bar) throws TheSkyIsFallingException, HellFrozeOverException, ShitInShitOutException


etc.

While you could say that all these exceptions are EntropyExceptions you could say:

public void foo(Bar bar) throws EntropyException

But why stop at that?

You might as well generalize it into

public void foo(Bar bar) throws Exception

And if you know that every method can throw an exception, you might as well say that

public void foo(Bar bar) implicit throws Exception

And, then you basically have RuntimeException
--
Viktor Klang

Rogue Scala-head

Blog: klangism.blogspot.com
Twttr: viktorklang

Jeff Grigg

unread,
Aug 18, 2009, 7:06:35 AM8/18/09
to The Java Posse
Regarding closing JDBC resources when exceptions happen...

I like to have one close in the 'finally' block, but execute only when
the reference isn't null. (Yes, that's evil -- but JDBC's
SQLException is evil.)

What I'd like to do is to add any 'close()' SQLException to the
exception that may have triggered the 'finally' block. But that's not
easy. Not standard Java either: Java supports "caused by", but not
collections of exceptions. :-[

Peter Becker

unread,
Aug 18, 2009, 7:11:52 AM8/18/09
to java...@googlegroups.com
Reinier Zwitserloot wrote:
> Yes, an utopia with checked exceptions is probably pretty decent, but
> as a practical matter they've been horribly abused. Not just by third
> party libraries; the java core library is inconsistent in places and
> has a lot of missing throws clauses in interfaces that can't be fixed
> because it would break backwards compatibility. Trying to fix these
> things is going to be even more painful than having to deal with
> checked exceptions in the current circumstance, which is one of the
> reasons why I advocate solving the problem directly. Such as offering
> an opt out mechanism where a programmer can explicitly 'correct' the
> compiler to say: Yah, I know, I know, this method call here DECLARES
> that it'll throw SomeCheckedException, and I neither catch it nor
> declare to throw it onwards, but, shaddap. I know what I'm doing, just
> compile this code, and let me get on with my day.
>
> It'll be abused, but the notion that exceptions will be abused in some
> fashion is what we have to deal with. The question is: How can we make
> sure the abuse is kept to a minimum? I'd assert that try {} catch
> ( Throwable t ) { Log.log(t); } is a much worse abuse than
> sneakythrowing.
>
Agreed.
> You get the benefit of being explicitly told about the checked
> exceptions that you ought to be checking, but when the theory fails
> due to a practical matter (the declared exception can't possibly
> happen, or you want to throw the exception onward but due to a badly
> designed interface you're not allowed to, etc, etc), you won't have to
> jump through a bunch of hoops, obscuring the exception as you go.
>
> Being able to return a disjoint type so you can cover extraordinary
> exit conditions that way instead of throwing exceptions for them could
> work, but I don't really know of any language that handles them all
> that well. The only way I can see how it could possibly work is
> pattern matching. Which scala can mostly do, can't it?
>
As far as I understand you can't just do something like this (in
Java-like syntax, but ignoring a few other things Java such as the
.class for types):

public Result|Error1|Error2 someMethod() {...}

public void someOtherMethod() {
var result = someMethod();
switch(typeof result) {
case Result:
processResult(result);
default:
handleError(result);
}
}

public void processResult(Result result) {...}

public void handleError(Error1|Error2 error) {
...code using anything on common supertypes of Error1/2...
}

Part of what I'd like to see is that there is no need to name the types
used. The signature of the last method should also be allowed to be
handleError(Error) assuming that both Error1 nad Error2 are subtypes of
Error (which is really just normal polymorphism since it implies that
the union is a subtype, too).

My Scala is not good enough to judge what is truly possible, but most
code I've seen seems to end up using Either in this case, which seems a
bit of a kludge -- particularly if you create a union of more than two
types. I'd be happy to hear about alternatives.

Peter

Michael Neale

unread,
Aug 18, 2009, 7:22:38 AM8/18/09
to The Java Posse
Lombok - is that named after Lombok in bali - near the island of
Java?

Peter Becker

unread,
Aug 18, 2009, 7:23:44 AM8/18/09
to java...@googlegroups.com
Is it really that bad? Most of the common exceptions shouldn't be there
at all, for example NullPointerException, ClassCastException and
ArrayStoreException are all just signs of a broken type system. Some of
the Errors seem unavoidable, but with the Exceptions I still prefer the
idea of actually managing them.

Note that one of the most important patterns for me is chained
exceptions. Somehow it took until JDK 1.4 until they got introduced and
even then not completely. But by chaining exceptions you can keep the
number of exceptions in each layer down and you also provide encapsulation.

In the end it comes down to a lot of different factors, including
personal taste. But I am still not willing to dismiss checked exceptions
as a generally bad idea.

Peter
> <mailto:michael.ne...@gmail.com>> wrote:
> >
> >> What do people think of the scala approach of no checked
> exceptions -
> >> even checked exceptions are not treated specially by the
> constructor
> >> (personally, I like it).
> >>
> >> On Aug 18, 12:55 pm, Christian Catchpole
> <christ...@catchpole.net <mailto:christ...@catchpole.net>>
> >> wrote:
> >>
> >>
> >>> No, i just let that go up. I really try to avoid the declare
> as null
> >>> then set thingy.
> >>>
> >>> On Aug 18, 12:03 pm, Casper Bang <casper.b...@gmail.com
> Blog: klangism.blogspot.com <http://klangism.blogspot.com>
> Twttr: viktorklang
>
> >

Michael Neale

unread,
Aug 18, 2009, 7:24:22 AM8/18/09
to The Java Posse
Or Maybe - (in which case you don't care about the None case, you just
need to handle it).

Michael Neale

unread,
Aug 18, 2009, 7:31:36 AM8/18/09
to The Java Posse
Proably would use a set of case classes I guess, but would end up
looking like a pretty version of that (someone like Viktor will
probably show us !).

Viktor Klang

unread,
Aug 18, 2009, 7:48:54 AM8/18/09
to java...@googlegroups.com
On Tue, Aug 18, 2009 at 1:31 PM, Michael Neale <michae...@gmail.com> wrote:

Proably would use a set of case classes I guess, but would end up
looking like a pretty version of that (someone like Viktor will
probably show us !).

As Peter Becker suggested previously in this thread, you could use the Either-type in Scala, or if you are adventurous: use the Box-type in Lift

scala> def foo[T](fun : => T) : Either[T,Exception] = try { Left(fun) } catch { case e : Exception => Right(e) } 
foo: [T](=> T)Either[T,Exception]

scala> def fooResult[T](fun : => T) : String = foo(fun) match { case Left(x) => "Yielded: " + x; case Right(x) => "Exception: " + x; }
fooResult: [T](=> T)String

scala> fooResult(10/0)
res0: String = Exception: java.lang.ArithmeticException: / by zero

scala> fooResult(System.currentTimeMillis)
res1: String = Yielded: 1250596147666


Box from Lift has a sligtly different semantics, it has 3 distinct states:

Full
Empty
Failure

while Either only has 2:

Left
Right


 

--
Viktor Klang

Rogue Scala-head

Blog: klangism.blogspot.com
Twttr: viktorklang

Paul King

unread,
Aug 18, 2009, 9:37:46 AM8/18/09
to java...@googlegroups.com
Lombok looks interesting. Groovy makes this sort of code very
palatable too, instead of:

> @Cleanup PreparedStatement ps = connection.prepareStatement
> (sql);
> @Cleanup ResultSet resultSet = ps.executeQuery();
> while (resultSet.next()) {
> // stuff
> }

You would do:

sql.eachRow(sql) { /* stuff */ }

Paul King

unread,
Aug 18, 2009, 9:39:08 AM8/18/09
to java...@googlegroups.com
I guess should have used a different variable name in the last example:

db.eachRow(sql) { /* stuff */ }

Cheers, Paul.

Alexey Zinger

unread,
Aug 18, 2009, 10:51:06 AM8/18/09
to java...@googlegroups.com
Maybe what this discussion needs is some real-world anecdotes of checked vs unchecked exceptions in production environments and how they helped or not to save the day.
 
Alexey
2001 Honda CBR600F4i (CCS)
1992 Kawasaki EX500
http://azinger.blogspot.com
http://bsheet.sourceforge.net
http://wcollage.sourceforge.net



From: Peter Becker <peter.b...@gmail.com>
To: java...@googlegroups.com
Sent: Tuesday, August 18, 2009 6:13:54 AM
Subject: [The Java Posse] Re: How do YOU handle Exceptions?

Casper Bang

unread,
Aug 18, 2009, 11:03:26 AM8/18/09
to The Java Posse
On 18 Aug., 16:51, Alexey Zinger <inline_f...@yahoo.com> wrote:
> Maybe what this discussion needs is some real-world anecdotes of checked vs unchecked exceptions in production environments and how they helped or not to save the day.

I would think it's a fairly real-world anecdote how no other language
following Java introduced checked exceptions. Also you will have a
much easier job coming up with language guro's against them than for
them I think.

/Casper

Alexey

unread,
Aug 18, 2009, 11:55:11 AM8/18/09
to The Java Posse
I'm not convinced of that. So far, most of the complaints come from
people talking about the imposition checked exceptions create on the
coder. There's grumbling of misuse and hiding of exceptions by
improper logging or catching and ignoring, but not much in the way of
real-world scenarios. Not saying those statements aren't grounded in
reality, but let's throw out some concrete situations to dissect and
see how they could have been helped.

I'm not a fan of how checked exceptions are used in specific API, JSE
included, but I'm not against the concept as a whole. Lately, I've
been working almost exclusively on web projects, many of them using
GWT. Some of those projects were started by my predecessor and, not
to put the guy down, but there's some horrendous exception handling
there. Lots of catch(Exception), inconsistent and often broken
logging, and all sorts of nasties like that. Some of the scenarios
that were very difficult to debug (and still are in some parts of the
systems) are the ones, where there's use of a 3rd party Excel
authoring library (jxl as I recall). Occasionally, the code comes
across a situation that breaks certain assumptions (unexpected
formatting, or the like) and those almost inevitably get buried in
ignored exception catches. I never get proper time to go through it
(not that I'm that excited to do it) and clean it up, and so time and
again we bump into some new extravagant way the system breaks.

Now, one would read this and say, "Aha! -- if only there were no
checked exceptions, your predecessor would have written his sloppy
code in a way that would allow those to propagate to the top layer
(servlet container) and you would have seen it in some log and
probably on some screen." Indeed, some of those exceptions are of
checked variety. However, the code was written in a manner that
didn't stand a chance. He simply assumed there would be no erroneous
situation and dealt wrote EVERYTHING (file IO, DB, parsing/formatting,
etc.) under a single try block and figured he'd just log whatever was
caught in one catch (reuse, right?). And in fact, there ARE plenty of
ways to handle these situations based on whatever kind of exception
might arise. For instance, multiple formats might be tried on a
single value before giving up, whereas a general Excel file read
exception is probably unrecoverable.

And then there's the unintended catching of RuntimeException that's
sprinkled around there that also just lumps lots of different
situations into one try/catch. This one can't be fixed by killing off
checked exceptions, obviously.

Overall, much of the problems could have been avoided by a better
internal API design, that would separate different layers of
functionality into finer granularity and would make it clear to the
developer how to handle each and every exceptional situation
differently, while still cleaning up resources when possible. So I
don't think simply eliminating checked exceptions would have been the
answer. I think both checked and unchecked have their place.
Remember, that just because Java is the only language with checked
exceptions, doesn't mean that it's a dead end. I do think that real
world implementations have scared some people off the idea.

Casper Bang

unread,
Aug 18, 2009, 12:35:11 PM8/18/09
to The Java Posse
Perhaps, but we're talking about a list with names like Bruce Eckel,
Anders Hejlsberg, Gilad Bracha, Guido van Rossum, Martin Fowler,
Martin Odersky, Ola Bini etc. Even Neal Gafter does not seem convinced
and I've heard similar things from Cay Horstman etc.

If only we could have a kind of optional checked exception, a form of
versatile and pluggable type system (sort of Gilad Bracha's way of
thinking), then one could say something like:

catch(new JDBCExceptionHandler(){
// Stuff...
}

Not sure if that makes sense though but I've often wanted something
like that.

/Casper

phil swenson

unread,
Aug 18, 2009, 1:19:19 PM8/18/09
to The Java Posse
I understand the theoretical benefit of checked exceptions, but
reality trumps theory. They simply don't scale and lead to swallowed/
hidden exceptions.
I've seen quite a few open source APIs that have "throws Exception" in
them. And generally the open source APIs are done by some of the best
coders!

Another issue I didn't mention is checked exceptions pollute the
interface. Lets say you have a public API (interface) and add a new
exception type. This makes every consumer of your API's code break.
This violates the concept of having an API "contract". So with
checked exceptions either you are forced to 1) violate the contract or
2) not throw the exception you want to throw and wrap it in an
unsuitable exception or 3) use a runtime exception. 3 is best:)

people are so concerned with not knowing what exceptions are thrown,
but if you test your projects you will discover when there are
exceptions that are thrown and you want to handle. It's a rare
occurrence. usually there is nothing you can do about it, so knowing
that it will be thrown doesn't really help you out. I mean seriously,
what do you do when you get a SQL Exception? it's almost always a
bug. and a bug that might not be discovered if you used a checked
exception and swallowed it.

Reinier Zwitserloot

unread,
Aug 18, 2009, 1:40:23 PM8/18/09
to The Java Posse
Yes. And the indonesian word for chili paste, which is also lombok.
("Spice up your java" is the tag line, after all.)

Reinier Zwitserloot

unread,
Aug 18, 2009, 1:52:53 PM8/18/09
to The Java Posse
Concrete examples:

Runnable does not let you throw Exceptions. Anyone up for defending
this grievous API design? The amount of annoyance that this is caused
me is almost limitless.


Servlets require you to wrap checked exceptions into a
'ServletException', which is almost as bad. *ANY* exception caused by
a servlet is cause to log it and return 500. Why the heck do I need to
wrap these things? Who is helped by that? Which code has become more
readable because of that?

InputStream.close() throws IOException. Nuff said.

NumberFormatException is a likely scenario that the calling code can
usually handle directly, yet its a runtime exception. Making the case
that IOException ought to be a runtime exception is a lot harder to
make, so this is quite inconsistent.

new String(whatever, "UTF-8"); throws an UnsupportedEncodingException.
The JVM Spec says that you aren't a JVM unless you support at least
the basic set of charsets. UTF-8 is there. So is ISO-8859-1, and so is
US-ASCII. Thus, that line ought to be throwing a VirtualMachineError
if UTF-8 is not found.

FilterInputStream and FilterOutputStream's methods throw IOException,
but if I feed it a ByteArrayInputStream, or I let it filter into a
ByteArrayOutputStream, then an IOException can never happen.

Any attempt to use a "closure" (anonymous inner class literal) where
the "closure" is handed off for immediate processing, right there on
the spot, nevertheless does not inherit the checked exceptions that
can legally be thrown on the declaration site. There are a number of
interfaces which are clearly supposed to be used this way, but its
impossible to get the API right for these things. This is why the BGGA
proposal has a very awkward part in it do deal with this issue.
Designing such interfaces with a 'throws Throwable' clause doesn't
help; you need to repeat the clause (1) and it would mean that calling
code has to now deal with all throwables. It's just a disaster. Here,
imagine you want to sort-in-place a list of files depending on their
canonical path:

Collections.sort(listOfFileObjects, new Comparator<File>() { public
int compare(File a, File b) { return a.getCanonicalPath().compareTo
(b.getCanonicalPath()); }});

Except the above code won't fly; getCanonicalPath throws IOException.
Even if I wrap this entire line in a try/catch block, that won't help.

How's that for examples?

Reinier Zwitserloot

unread,
Aug 18, 2009, 1:56:01 PM8/18/09
to The Java Posse
Exceptions aren't just for exceptional situations. This seems
perfectly legit to me:

public class BankAccount {
public void transferFundsTo(BankAccount other, int amount) throws
InsufficientBalanceException {}
}


The InsufficientBalanceException is not an exceptional situation. It
happens all the time, it's an intrinsic part of the design process.
It's exceedingly likely the calling code will need to deal with the
SITUATION that the bank account has insufficient funds. However, if
this method just returned a boolean, they might forget to check.

Proper usage of checked exceptions is actually that the exceptional
cases (IOException, SQLException...), AND cases where the condition
isn't particularly exceptional, but it is extremely unlikely that your
average caller can do anything about it, you ought to be using
runtimeexception (that would be the vast majority of them). For
conditions that are NOT exceptional, you should be using checked
exceptions. Of course, one mans exceptional usecase is another mans
alternate exit condition, so this is fuzzy logic at best.

Jess Holle

unread,
Aug 18, 2009, 2:22:13 PM8/18/09
to java...@googlegroups.com
Reinier Zwitserloot wrote:
Concrete examples:

Runnable does not let you throw Exceptions. Anyone up for defending
this grievous API design? The amount of annoyance that this is caused
me is almost limitless.
  
Well Runnable is really for cases where run() should eat any exceptions other than things like VirtualMachineErrors -- and should not be used for anything else.

That said, this is exactly where BGGA's exception transparency should come into play -- to allow you to define:
public interface Callable<T,E>
{
  public T  call() throws E;
}
I will almost certainly get BGGA's proposed syntax muddled here, but the important thing here is that call() could throw a precise set of checked exceptions and this set would be bubbled up in generic algorithms (rather than Exception as in Callable<T> today), e.g.
public <T,E> visit( Callable<T,E> visitor ) throws SQLException, E;
or some such.  The actual list of checked exceptions emanating from visit would be SQLException, IOException, MalformedURLException if E was IOException, MalformedURLException.

One can still wrap the exception at any point along the way, of course, but one is not forced to arbitrarily do so at various points as one is today just because of the imprecision of a generic algorithm's declaration.

--
Jess Holle

Mario Camou

unread,
Aug 18, 2009, 2:27:08 PM8/18/09
to java...@googlegroups.com
The way I normally think about it is, business exceptions are (usually) checked exceptions. Error conditions are RuntimeExceptions.

-Mario.

--
I want to change the world but they won't give me the source code.

Reinier Zwitserloot

unread,
Aug 18, 2009, 6:06:32 PM8/18/09
to The Java Posse
BGGA's checked exception handling is extremely complex. I don't like
it at all.

I'd much rather have a closure proposal where a method that takes a
closure that has tennant's correspondence principle is strictly
enforced by the compiler to keep the closure stack-safe. In other
words, legal operations are:

1. Running the closure,
2. Grabbing info off of the closure object (running its toString or
some such)
3. passing it on to another method that accepts closures.

You can't assign it to another variable, give it to a method that
isn't designed with these restrictions in mind, assign it to a field,
or letting it escape any other way. This is nice for checked
exceptions, as you can just ignore them, it'll all sort itself out,
but it's also nice because with that restriction, you'll never run
into the situation that break / continue / return in the closure
becomes meaningless (those 3 statements become meaningless if the
stack is gone. The for loop you're trying to break out of is long
gone, so, what exactly is break supposed to do? In BGGA you'd get a
TransferException at runtime. Meh).

If the compiler knows FOR SURE that a given closure is always run so
that the stack as it was when you defined it exists, then there's no
need for all the checked exception generics. Any exception you could
legally throw at the point where you defined the closure is legal to
throw in the closure. Example:

Let's say that, purely for arguments sake, "do" as a keyword modifier
of a parameter signals that it can be a closure, and that you can only
make parameters that are SAMs (types that carry exactly 1 abstract
method).

Then you could write Collections.sort as:

public class Collections {
public static <T> void sort(List<T> list, do Comparator<? super T>
comparator) {
//do your sort thing.
}


The compiler will then strictly enforce that the sort method doesn't
allow the comparator reference to escape (for its function, there's no
need for that. Contrast to e.g. TreeSet's (Comparator) constructor,
where the comparator must be stored in a field in the treeset, which
would count. You could not stick a 'do' in front of that, the compiler
would refuse to compile that constructor).

Then, you would be able to legally do this in your code:

try {
Collections.sort(someStringList, #(String a, String b) { new File
(a).getCanonicalPath().compareTo(new File(b).getCanonicalPath()) });
} catch ( IOException e ) {
//deal with exception.
}

Please don't get hung up on the syntax, consider it pseudocode. I'm
trying to convey the idea that you're calling code that declares
'throws IOException' (getCanonicalPath does that) in a method
(Comparator.compare) which doesn't even let you declare 'throws
IOException'. The compiler will accept this because it knows, _FOR
SURE_, that the closure is always run so that the stack is intact; in
other words, if an IOException does occur, either something in the
mechanics of Collections.sort handles it, or, if it falls through, the
catch block here will handle it. There's no violation of the checked
exception type system; you can't have an IOException in a place that
isn't prepared to handle them.

In BGGA, the mechanism by which the compiler ensures the checked
exception type system is valid is entirely different: Collections.sort
would have to be changed (which isn't possible, backwards
compatibility being the holy grail that it is, so we'd need a sort2
method. Yich!) to accept a parameter 'E' which is the exception type
(s) thrown by the code block. Because you can throw multiple things,
BGGA has a special syntax for this:

public static <T, throws E> void sort(List<T> list, {T => int throws
E} closure) throws E { /*sort method */ }

Here the compiler just binds E to the appropriate exception type, and
as a result, due to the 'throws E' on the sort method itself, this
propagates out.

Now, BGGA has added quite a bit of complexity to make this work:

- you have this special 'throws E' syntax, which does a special
thing: It will match multiple exception types. so, if you type "throws
IOException, SQLException", and you're implementing a method with
'throws E' where the E is also specified in the generics type var name
as 'throws E', then E will be [IOException, SQLException], which is
something new - having 1 generics letter mean 2 different types.

- you need to have rather a lot of 'throws E' everywhere. In that
sort line, you have 3 mentions: In the generics var name, in the
function type, and in the method body. Theoretically it could be
different, but that's the pattern in 95% of all cases: The closure can
throw something, and the method, which operates on the closure, just
wants these exceptions to fall right out.

This notion I have of enforcing a closure to run inside stack is also
present in BGGA; after the first prototype, BGGA's break/return/
continue transparency was considered unwieldy because those terms are
meaningless if the stack is gone. Therefore, 2 closure types exist,
differentiated by the perl cartoon swear-esque => and ==> (I forgot
which one meant safe and which one meant unsafe), and you can have
long returns/breaks/continues in only one of the two.


So, if you've got this massive batch of complexity, why not run with
it and at least drop the 'throws E' stuff? Technically the 'throws E'
mechanism of BGGA is more powerful, but I can't think of very many use
cases where you'd ever want to do something with it other than just
pass exceptions right through. By doing it my way you can much more
easily adapt existing code: Just because a parameter has a 'do'
keyword does not mean you HAVE TO pass in a closure. You can pass in
any old Comparator, created in whatever way you like. The 'do' keyword
would simply mean: If you _want me to_, I can handle a closure here,
but it's not mandatory. Therefore, updating an api to add a 'do'
keyword preserves backwards compatibility perfectly. You could just
never remove a 'do' keyword without breaking existing code.


I will be submitting a proposal along these lines (checked exceptions
sorted out this way, a focus on SAMs and not function types, separate
syntax for code blocks and for when you just want to write an
anonymous inner class literal, but with less boilerplate) - if the
closure discussion ever flares up again. Right now closures seem to be
going nowhere, so I'd rather focus on other things. Like project
lombok.

On Aug 18, 8:22 pm, Jess Holle <je...@ptc.com> wrote:
> Reinier Zwitserloot wrote:
> > Concrete examples:
>
> > Runnable does not let you throw Exceptions. Anyone up for defending
> > this grievous API design? The amount of annoyance that this is caused
> > me is almost limitless.
>
> Well Runnable is really for cases where run() should eat any exceptions
> other than things like VirtualMachineErrors -- and should not be used
> for anything else.
>
> That said, this is exactly where BGGA's exception transparency should
> come into play -- to allow you to define:
>
>     public interface Callable<T,E>
>     {
>       public T  call() throws E;
>     }
>
> I will almost certainly get BGGA's proposed syntax muddled here, but the
> important thing here is that call() could throw a precise set of checked
> exceptions and this set would be bubbled up in generic algorithms
> (rather than Exception as in Callable<T> today), e.g.
>
>     public <T,E> visit( Callable<T,E> visitor ) throws SQLException, E;
>
> or some such.  The actual list of checked exceptions emanating from
> visit would be SQLException, IOException, MalformedURLException if E was
> IOException, MalformedURLException.
>
> One can still wrap the exception at any point along the way, of course,
> but one is not /forced /to arbitrarily do so at various points as one is

James Iry

unread,
Aug 18, 2009, 7:06:01 PM8/18/09
to java...@googlegroups.com
On Tue, Aug 18, 2009 at 3:13 AM, Peter Becker <peter.becker.de@gmail.com> wrote:

What I would really like to see is a meet/or/disjunction/union operator
in the type system, with a case-like construct to resolve the resulting
types. Scala has two things that are halfway there (Either, case
classes), but neither is the full monty.

Few type systems have true union types.  The algebraic data types of the ML and Haskell families, for instance, do not allow unioning of types without explicitly creating a new type with its own "constructors".  See Either which in Haskell looks like.  

data Either a b = Left a | Right b

In Scala, Haskell, or SML Either is really just a way of faking union typing in a type system that doesn't do union typing.

Java is actually very unusual in that the small bit of its type system devoted to exceptions basically has union types.  If a method says it throws A,B,C then the union "A,B,C" forms a type and the type "A,B" is a subtype, the type "A,B,C,D" is a supertype.  With regards to declared exceptions on methods Java is covariant.  I know that's not how checked exceptions are normally presented, but that's how the type rules work.

But then Java, as usual, isn't very regular about this union typing business.  You can write

Integer myFunction(File file) throws IOException, MyBusinessException {...}

But if you try to make it "first class" with something like

interface Function<In, Out, Exc> {
  Out apply(In in) throws Exc;
}

You can't then write something like

new Function<File, Integer, {IOException, MyBusinessException}> {...}

Your first class function has to pick one exception or declare that it throws a common supertype.

Project Coin proposed the ability to catch mutliple exception types with one catch block.  That can be seen as extending union typing just a touch further, but it still doesn't cover exception types as type parameters.

It's not surprising to me at all that Java remains virtually the only language with checked exceptions.  They might be a fine idea, but making them usable and consistent across the language is very tough business.  Checked exceptions are what's called an effects system, which is a way to extend a type system so that functions describe effects they might have beyond computing a value.  Creating an effects system that is usable and consistent across the language is very much ongoing research.  See Disciple http://www.haskell.org/haskellwiki/DDC/EffectSystem, but I warn you it's not for the faint of heart.

Alex Buckley

unread,
Aug 18, 2009, 9:06:33 PM8/18/09
to The Java Posse
I'm slightly embarrassed to admit I'm a fan of http://bugs.sun.com/view_bug.do?bug_id=6534270

On Aug 15, 5:56 am, Jeff Grigg <jeffgr...@charter.net> wrote:
> I like the beauty and simplicity of completely empty catch blocks.  >;->  OK, some developers, to comply with corporate documentation
>
> standards, put comments there.   >;->
>
> (Reality is that I'll usually wrap checked exceptions in
> RuntimeExceptions at a low level, and then catch Exception at the top
> level -- to log it and abort or retry the transaction or user action.
> There's a lot of really bad code out there that misuses exceptions and
> does exception handling cleanup wrong.  It's a problem!!)

Christian Catchpole

unread,
Aug 18, 2009, 9:17:46 PM8/18/09
to The Java Posse
People have suggested similar keywords - I don't like the idea of
wrapping in a RuntimeException, but as we know, checked exceptions are
a figment of Java's imagination and are simply enforced by the
compiler.

Why not simply allow them to bubble up as their original exception,
just remove the need for checking them.

void thing() coverts IOException {
}

Does anyone know, if you were to remove the throws declarations from a
method in a class, would the JVM still validate the class file, if the
method was clearly throwing checked exceptions? I assume it would
allow it. I guess this is how Scala works.

On Aug 19, 11:06 am, Alex Buckley <alex.buck...@sun.com> wrote:
> I'm slightly embarrassed to admit I'm a fan ofhttp://bugs.sun.com/view_bug.do?bug_id=6534270

Jess Holle

unread,
Aug 18, 2009, 9:49:36 PM8/18/09
to java...@googlegroups.com
BGGA's exception transparency hinges on disjunctive types, of course...

Jess Holle

unread,
Aug 18, 2009, 9:58:09 PM8/18/09
to java...@googlegroups.com
Reinier Zwitserloot wrote:
BGGA's checked exception handling is extremely complex. I don't like
it at all.
  
You can gripe about that, but it is the only thing that really makes a code block work "normally".

If you have something like:
for ( ... )
{
  // some code that throw IOException
}
then you'd expect to have to catch IOException or declare "throws IOException".

If you don't have exception transparency, then when you use closures to do something like
forEachWombat( ... )
{
   // do some stuff that throws IOException
}
You'd get totally different behavior -- which is *not* acceptable in my book.

Exception transparency is complex in terms of implementation -- but rather simple in terms of usage.  It's really a missing piece of Java generics and exception handling in Java as I see.

As for Collections.sort() -- if you want this to allow throwing of checked exceptions from the Comparable then this is a dramatic change in the contract and, yes, Collections.sort() would have to be reimplemented.  There's still a big different between "public T foo()" and "public T foo() throws E" -- the former is saying only serious unforeseen runtime exceptions could possibly occur in foo() -- that's the contract.  That the Comparable contract and changing that is a big change.  On the other hand, that's not to say that Callable wouldn't be a lot better as "public T call() throws E" than "public T call() throws Exception".

--
Jess Holle

Casper Bang

unread,
Aug 18, 2009, 10:03:39 PM8/18/09
to The Java Posse
According to Joshua Engel's "Programming for the Java VM", that is not
part of the verification algorithm. I had planned to do something
similar in Kijaro, and instead have NetBeans issue warnings when
neglecting to catch a checked exception - but I never really found out
how to override NetBeans version of javac, I assume its the same
problem Reinier struggles with for Lombok.

/Casper

On 19 Aug., 03:17, Christian Catchpole <christ...@catchpole.net>
wrote:

James Iry

unread,
Aug 18, 2009, 10:06:10 PM8/18/09
to java...@googlegroups.com
I really hate phrasing something like this as being a "figment."  That's like saying that "short" and "char" are figments of the JVM's imagination because it's all just bits.

None-the-less, the answer is that checked exceptions are enforced by Java's static system and not by the JVM at all.  So Scala, Groovy, JRuby, etc pretty much just ignore them.

Reinier posted a very clever way to take advantage of the fact that casts to type parameters aren't checked to effectively cast away the "checkedness" of an exception without wrapping it, which I'll copy in case you can't find it

public class Sneak {
    public static RuntimeException sneakyThrow(Throwable t) {
        Sneak.<RuntimeException>sneakyThrow0(t);
        return null;
    }

    @SuppressWarnings("unchecked")
    private static <T extends Throwable> void sneakyThrow0(Throwable t)
            throws T {
        throw (T) t;
    }

}


It gets used like

public class Test {
    public void test() {
        throw sneakyThrow(new IOException("this should be checked, but it's not!"));       
    }
   
    public static void main(String[] args) {
        try {
            new Test().test();           
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

It is mildly annoying that you can't catch IOException here because Java says it can't possibly happen.  Silly Java, we just pervted you so that it can!

Casper Bang

unread,
Aug 18, 2009, 10:11:39 PM8/18/09
to The Java Posse
On 19 Aug., 04:06, James Iry <james...@gmail.com> wrote:
> I really hate phrasing something like this as being a "figment."  That's
> like saying that "short" and "char" are figments of the JVM's imagination
> because it's all just bits.

Yeah well, it depends how you look at it I suppose. I would also claim
generics to be a figment of the JVM's imagination, since you can not
implement Comparable<Integer> and Comparable<BigInteger> due to it
being an emulated construct at the parser level. Other languages with
real generics have no problem with that, in Java all of a sudden you
are going to need anonymous inner classes as dispatch adapters.

/Casper

Christian Catchpole

unread,
Aug 18, 2009, 10:24:50 PM8/18/09
to The Java Posse
I can think of a hack. But it's not a very nice one and probably has
limited use. You compile with "throws Exception" on the method and
then edit the method signature in the resulting byte code. Perhaps
easier than hacking javac.

Message has been deleted

James Iry

unread,
Aug 18, 2009, 11:10:14 PM8/18/09
to java...@googlegroups.com
On Tue, Aug 18, 2009 at 7:11 PM, Casper Bang <caspe...@gmail.com> wrote:

Yeah well, it depends how you look at it I suppose. I would also claim
generics to be a figment of the JVM's imagination, since you can not
implement Comparable<Integer> and Comparable<BigInteger> due to it
being an emulated construct at the parser level.

Well, not parser - type checker.  But I know what you mean.  Still, Haskell has a construct called "newtype" which creates a type whose representation is exactly the same as another type, but that the type system treats as compeltely different.  That might allow you to say that inches are a type distinct from centimeters even though they are both represented with rational numbers.  The fact that newtypes are guaranteed to be erased for efficiency's sake doesn't make them any more "figmentary" than any other type.
 
Other languages with
real generics have no problem with that, in Java all of a sudden you
are going to need anonymous inner classes as dispatch adapters.


"Other languages...real generics."  C++ of course uses templating to do polyinstantiation (List<Foo> is a different class from List<Bar>) and mangles the hell out of names so you'd end up with compare_$_Integer and compare_$_BigInteger functions (or whatever your compiler does with them).  That's all well and good as long as you stick to the same C++ compiler.  But try to interop with another C++ compiler or another language like C and you suddenly start wishing all that type information would be erased.  It also makes it damn hard to extend C++ with something like Java's wildcards or Scala's existintials and definition site variance. On the JVM side, Groovy has no problem consuming Java even though parameterized types are way beyond it, just try creating a dynamic language that so seamlessly interops with C++.  So, point 1: erasure aids in interop and flexibility.

In Haskell implementations are pretty free to do what they want but they tend to erase most types, except perhaps in distinguishing what Java people would call "primitives."  Haskell allows overloading but does it through a mechanism called a "type class" which is usually (though not always) implemented with dictionary passing (you can think of this as being somewhat like passing around a strategy object...sorta). So, point 2: different language semantics make erasure more palatable, and in Java different programming styles make it more or less palatable.

Peter Becker

unread,
Aug 18, 2009, 6:05:53 PM8/18/09
to java...@googlegroups.com
Maybe is good if something may or may not be there such in a dictionary
lookup. The element not being available is a normal occurrence in that case.

In the case of errors it would hide what the actual error was.

Peter


Michael Neale wrote:
> Or Maybe - (in which case you don't care about the None case, you just
> need to handle it).
>
> On Aug 18, 6:43 pm, Peter Becker <peter.becker...@gmail.com> wrote:
>
>> In Scala you get the Either type. That is superior for most cases where
>> one might use checked exceptions in Java.
>>
>> I have used that style in Java, but you usually don't make friends with it.
>>
>> Peter

Peter Becker

unread,
Aug 18, 2009, 6:24:17 PM8/18/09
to java...@googlegroups.com
Let me just say that I fully agree with this post. I believe most people
look at the way checked exceptions are used and since that is mostly bad
they assume the whole idea is bad. Since I can think of nicer solutions
with checked exceptions for pretty much everything people complain about
I am not willing to follow their argument.

But I suspect we would need a full library stack written with checked
exceptions in a better manner to see if they can work.

Peter

Peter Becker

unread,
Aug 18, 2009, 6:48:54 PM8/18/09
to java...@googlegroups.com
phil swenson wrote:
[...]
> Another issue I didn't mention is checked exceptions pollute the
> interface. Lets say you have a public API (interface) and add a new
> exception type. This makes every consumer of your API's code break.
> This violates the concept of having an API "contract". So with
> checked exceptions either you are forced to 1) violate the contract or
> 2) not throw the exception you want to throw and wrap it in an
> unsuitable exception or 3) use a runtime exception. 3 is best:)
>
So you are saying it is better to quietly change behaviour than to make
a change to an API that breaks source compatibility? I certainly would
not agree to that.
> people are so concerned with not knowing what exceptions are thrown,
> but if you test your projects you will discover when there are
> exceptions that are thrown and you want to handle. It's a rare
> occurrence. usually there is nothing you can do about it, so knowing
> that it will be thrown doesn't really help you out. I mean seriously,
> what do you do when you get a SQL Exception? it's almost always a
> bug. and a bug that might not be discovered if you used a checked
> exception and swallowed it.
>
Sorry, but I call BS on that. SQLExceptions get thrown when the DB
server is down or in trouble, when the network has issues and possibly
other reasons that you do not encounter in test environments, so your
testing won't help. Of course you can let it go through and just let
your application provide with a generic error message, but there might
be better ways of dealing with such an issue, in particular if the DB in
question is not your only data source. For example: if your ads are
served from a database and that is down, you probably want to fall back
to some standard display, not a 500. Of course you could do that by
catching Exception/Throwable around the component responsible, but the
person integrating the system has to be aware that something can go
wrong there.

I guess you could just operate on the assumption that everything can
fail and provide a generic error handler for each component, but I don't
like this approach at all. In particular I believe that there should be
parts of your code that do not throw exceptions at all. With checked
exceptions you can distinguish the ones that do from the ones that don't.

That approach just doesn't work well in Java because JDK libraries
already throw a lot of Exceptions where they shouldn't (in particular
the dreaded NPE). But that doesn't seem to allow concluding that the
idea of checked exceptions is broken as such.

Peter

Peter Becker

unread,
Aug 18, 2009, 6:56:57 PM8/18/09
to java...@googlegroups.com
Reinier Zwitserloot wrote:
> Concrete examples:
>
> Runnable does not let you throw Exceptions. Anyone up for defending
> this grievous API design? The amount of annoyance that this is caused
> me is almost limitless.
>
Where would that exception go?
> Servlets require you to wrap checked exceptions into a
> 'ServletException', which is almost as bad. *ANY* exception caused by
> a servlet is cause to log it and return 500. Why the heck do I need to
> wrap these things? Who is helped by that? Which code has become more
> readable because of that?
>
It makes some sense to me. The servlet container cares only about the
fact that the servlet failed, the question why is rather secondary on
that level. You could also imagine that subtypes are used to distinguish
the actual problem.

If you just allow any exception to go through (e.g. by letting the
methods throw Exception on the API level), programmers will forget to
handle things they could handle.
> InputStream.close() throws IOException. Nuff said.
>
That only proves that exceptions are used badly in the JDK.
> NumberFormatException is a likely scenario that the calling code can
> usually handle directly, yet its a runtime exception. Making the case
> that IOException ought to be a runtime exception is a lot harder to
> make, so this is quite inconsistent.
>
I totally agree, not catching NumberFormatException is something I
consider a code stink -- unless the parsed string is a constant it is
probably wrong. If it is a constant it begs the question: "Why?".
> new String(whatever, "UTF-8"); throws an UnsupportedEncodingException.
> The JVM Spec says that you aren't a JVM unless you support at least
> the basic set of charsets. UTF-8 is there. So is ISO-8859-1, and so is
> US-ASCII. Thus, that line ought to be throwing a VirtualMachineError
> if UTF-8 is not found.
>
IMO there should be accessor methods for the common encodings. Again:
bad API design in the JDK, which we all seem to agree upon.
> FilterInputStream and FilterOutputStream's methods throw IOException,
> but if I feed it a ByteArrayInputStream, or I let it filter into a
> ByteArrayOutputStream, then an IOException can never happen.
>
Which could be solved by having safe and unsafe versions of the interface.
> Any attempt to use a "closure" (anonymous inner class literal) where
> the "closure" is handed off for immediate processing, right there on
> the spot, nevertheless does not inherit the checked exceptions that
> can legally be thrown on the declaration site. There are a number of
> interfaces which are clearly supposed to be used this way, but its
> impossible to get the API right for these things. This is why the BGGA
> proposal has a very awkward part in it do deal with this issue.
> Designing such interfaces with a 'throws Throwable' clause doesn't
> help; you need to repeat the clause (1) and it would mean that calling
> code has to now deal with all throwables. It's just a disaster. Here,
> imagine you want to sort-in-place a list of files depending on their
> canonical path:
>
> Collections.sort(listOfFileObjects, new Comparator<File>() { public
> int compare(File a, File b) { return a.getCanonicalPath().compareTo
> (b.getCanonicalPath()); }});
>
> Except the above code won't fly; getCanonicalPath throws IOException.
> Even if I wrap this entire line in a try/catch block, that won't help.
>
> How's that for examples?
>
A nice list of examples where checked exceptions don't work well in the
JDK. The latter points to an issue between checked exceptions and
closures in the Java context. Does that in any way imply that the idea
of checked exceptions is bad in general or that it is impossible to use
checked exceptions in a positive way in Java? I don't see that yet.

Peter

Peter Becker

unread,
Aug 18, 2009, 11:07:46 PM8/18/09
to java...@googlegroups.com
I agree that there is a blurry line between exception and alternate
return value and as stated elsewhere I would prefer a union type in most
cases.

In your example the exception should be reasonable exceptional, though
-- after all people should not try a transfer unless they checked the
balance first. I guess it all depends on how you define "exceptional".

Peter

Casper Bang

unread,
Aug 18, 2009, 11:31:23 PM8/18/09
to The Java Posse
Well actually, Stephen Colebourne has made is real easy to hack on the
Java compiler - especially small hacks strictly at the parser level,
which we're talking about here. If you want to try it check out a
branch of Kijaro, locate the Check.java class and the methods matching
the signatures:

boolean isUnchecked(ClassSymbol exc)
boolean isUnchecked(Type exc)

Short circuit these by always returning true and... voila, no more
checked exceptions.

/Casper

On 19 Aug., 04:24, Christian Catchpole <christ...@catchpole.net>
wrote:

Casper Bang

unread,
Aug 18, 2009, 11:40:02 PM8/18/09
to The Java Posse
> especially small hacks strictly at the parser level

Ok yeah, I know technically it's at the semantic analysis level, but I
always think of the entire front-end (lexer, parser, semantic
analysis) as just the parser. Somewhat simpler than optimizer and
emitter.

/Casper

Christian Catchpole

unread,
Aug 19, 2009, 1:49:22 AM8/19/09
to The Java Posse
Java Exception handling technique number 284. Eat.

http://twitpic.com/efxij

Ben Schulz

unread,
Aug 19, 2009, 2:58:42 AM8/19/09
to The Java Posse
> I'd much rather have a closure proposal where a method that takes a
> closure that has tennant's correspondence principle is strictly
> enforced by the compiler to keep the closure stack-safe. In other
> words, legal operations are:
>
> 1. Running the closure,
> 2. Grabbing info off of the closure object (running its toString or
> some such)
> 3. passing it on to another method that accepts closures.

Wouldn't you lose the ability to parallelize? I might want to find an
element in a collection that satisfies a certain predicate. The
"first" thread to find one gets to return its findings, the others are
ignored.

With kind regards
Ben

Peter Becker

unread,
Aug 19, 2009, 4:03:03 AM8/19/09
to java...@googlegroups.com
Interestingly Java's generics allow the dual construction on interfaces:

public <T extends Interface1 & Interface2> void someMethod(T param) {...}

I really like the idea of having the anonymous unions/joins and
considering that the resulting type system should be a complete lattice
they sound manageable to me -- both for the compiler and the human
reader. Does anyone know reasons why no language seems to have this feature?

Peter

Reinier Zwitserloot

unread,
Aug 19, 2009, 7:14:23 AM8/19/09
to The Java Posse
So there IS a bug for that.

I've added a link to http://bugs.sun.com/view_bug.do?bug_id=6534270 to
the documentation for lombok's @SupressWarnings, which does the exact
same thing.

Christian: If you go in with a class file editor and remove the throws
clauses, the code will continue to run just fine. The validator will
NOT choke on it. I'm sure of that bit, and I'm almost sure that you
may catch a checked exception that no statement in the try block could
possibly throw, as well. javac won't compile such code, but again
that's just javac, and not a JVM thing.

On Aug 19, 3:06 am, Alex Buckley <alex.buck...@sun.com> wrote:
> I'm slightly embarrassed to admit I'm a fan ofhttp://bugs.sun.com/view_bug.do?bug_id=6534270

Ben Schulz

unread,
Aug 19, 2009, 7:21:26 AM8/19/09
to The Java Posse
> I really like the idea of having the anonymous unions/joins and
> considering that the resulting type system should be a complete lattice
> they sound manageable to me -- both for the compiler and the human
> reader. Does anyone know reasons why no language seems to have this feature?

I'm not much of a PLTist, but I'm guessing the reason uions don't make
it into general purpose, object oriented languages is that they're
inherently structural. Just a guess though. (The alternative is having
to check the runtime type and downcast, which pretty much defeats the
purpose.)

With kind regards
Ben

Reinier Zwitserloot

unread,
Aug 19, 2009, 7:33:33 AM8/19/09
to The Java Posse
Yes, it would lose you the ability to parallelize. There may be a way
out of this: Have the following system call:

public class System {
public static <R> R unsafe(do R closure) { return closure; }
}

The above code would not compile (you may not let a 'do' parameter
escape, but the method is hardcoded into the class library so that it
does in fact compile. You can now remove the 'you may not let your
closure escape' clause, at your own peril, by unlinking it like so:

Runnable youCanStoreMeNow = unsafe(parameter);

The unsafe method would explain in the javadoc that you need to take
on ALL RESPONSIBILITY to transport any long effects back to the
originating thread. So, you need to transport any and all exceptions
that fall out of youCanStoreMeNow back to the originating thread, and
the same goes for the throwables that are used to implement long break/
return/continue (see the BGGA proposal for more details on those).
This is clearly 'here be dragons' territory, but how often exactly
does one write a library for parallelizing things? Maybe like 5 times
in the entire world? Doesn't everyone else just use forkjoin? So, I'm
perfectly allright with having the type system be no help whatsoever
to you in the exceedingly rare circumstance when the rocket scientists
go write this function.

Casper Bang

unread,
Aug 19, 2009, 7:33:35 AM8/19/09
to The Java Posse
I can confirm this is practice, in fact, the modification to
Check.java I described a few posts ago would also allow compilation of
code with catch clauses of checked exceptions not really being thrown.

/Casper

Reinier Zwitserloot

unread,
Aug 19, 2009, 7:54:00 AM8/19/09
to The Java Posse
Replies inline. The problem is simply this: You think I was trying to
argue against checked exceptions in general. I wasn't. I was arguing
that the checked exception system isn't perfect, and therefore
programmers need to be given a tool to say to the compiler: I know
better than you. Stop whining.

More specific arguments follow below, inline.

On Aug 19, 12:56 am, Peter Becker <peter.becker...@gmail.com> wrote:
>
> > Runnable does not let you throw Exceptions. Anyone up for defending
> > this grievous API design? The amount of annoyance that this is caused
> > me is almost limitless.
>
> Where would that exception go?

The same place the RuntimeExceptions thrown by the runnable go. Your
argument only makes sense if Runnable was precluded from throwing -any
and all- exceptions. That's not true. What possible use is there for
someone invoking a Runnable (which after all stands for: I have no
idea what this does, other than run... something...) - to
differentiate between checked exceptions and unchecked exceptions? The
thing threw an exception. It doesn't matter what kind of exception was
thrown.

So, for Thread, that would be: The exception handler of that thread.

>
> It makes some sense to me. The servlet container cares only about the
> fact that the servlet failed, the question why is rather secondary on
> that level. You could also imagine that subtypes are used to distinguish
> the actual problem.

Sure, and if ServletException had a mechanism to specify certain extra
info (such as which error code and message to return), that would be
great stuff. But either way, a servlet container MUST handle *ANY*
exception falling out of a servlet (sneakyThrow, scala, jruby, jython,
any other non-java language on the VM, and mixing class files from
different compile runs can ALL result in a method throwing a checked
exception it didn't declare, so you already have to handle them!)

>
> If you just allow any exception to go through (e.g. by letting the
> methods throw Exception on the API level), programmers will forget to
> handle things they could handle.

Idiots write idiot code. But, okay, I'll roll with your argument: Then
why isn't there a mechanism to escape it? Why can't I say: Nono,
compiler, I did not forget anything, this is what I want. Shut your
yap. You're not really going to argue with me that there is no
inconvenience at all here, right?


>> InputStream.close() throws IOException. Nuff said.
>
> That only proves that exceptions are used badly in the JDK.

That "only" proves? The JDK abuses checked exceptions - That's a
pretty big deal! That's the whole point! That's why the language needs
an escaping mechanism.

The further damage caused by bad coders abusing the escaping mechanism
are, in my opinion, much, __much__ smaller than the potential further
damage that would no longer becaused because the mechanism is
available. The occasional explicitly supressed checked exception that
should have been handled is far less of a crime than code littered
with this abomination:

try {
something();
} catch ( IOException e ) {
e.printStackTrace();
//TODO Eclipse auto-generated this. The programmer never looked at
it again, logging to system.err is just about the worst thing you
could do here, and the original programmer only hit quickfix-add try
catch block because he couldn't throw it onwards because he's
implementing a servlet, or a runnable.
}

Sure, an idiot coded that. But we're all idiots some of the time, and
you yourself put 'idiots exist' on the table as a legal line of
reasoning.

>> FilterInputStream and FilterOutputStream's methods throw IOException,
>> but if I feed it a ByteArrayInputStream, or I let it filter into a
>> ByteArrayOutputStream, then an IOException can never happen.
>
> Which could be solved by having safe and unsafe versions of the interface.
>

Do you realize how much code duplication that would require? Exactly
_BECAUSE_ you can't circumvent checked exception checking, you'd
actually have to copy/paste every method. I cannot put into words the
insanity of a system that would _require_ you to copy/paste vast
tracts of code just to satisfy a system that is principally designed
to help code maintainance. Talk about bass ackwards. In practice, you
would most likely implement this by.... employing a sneaky throw hack.
I can scarcely imagine a better case for enshrining sneaky throwing
into the JLS, than this line of reasoning.

Reinier Zwitserloot

unread,
Aug 19, 2009, 7:55:32 AM8/19/09
to The Java Posse
Jess, I think you misunderstand my closure proposal.

It *DOES* have exception transparency. That's in fact exactly what it
has.

You further claim that you can't add exception transparency to
Collections.sort() without making a change to the API. This isn't
true! Read my post again - in my proposal, Collections.sort can be
retrofitted with full migration and backwards compatibility to support
exception transparency.

Jess Holle

unread,
Aug 19, 2009, 7:58:19 AM8/19/09
to java...@googlegroups.com
I see this as an important change quite apart from the current debate.

Catching an exception that cannot be thrown should be a *warning* not an error.

I'm sick of having code stop compiling because someone stopped throwing a checked exception!  That should *not* be a breaking change.  There is justification for a warning -- something changed that you might want to look into and clean up accordingly -- but there's no cause for an error.

This would be my #1 gripe about javac -- bar none.

Casper Bang

unread,
Aug 19, 2009, 8:10:06 AM8/19/09
to The Java Posse
> Catching an exception that cannot be thrown should be a *warning* not an
> error.

I totally agree, talk about idiosyncrasies getting in the way of the
job. Anyway, if someone wants to give it a try, grab this build of
javac:
http://82.103.135.236/javac.jar

And notice there's no problem compiling something like this:
public class CheckedExceptionTest{
public static void main(String... args){
Thread.sleep(100); // Throws InteruptedException (checked)
try{
System.out.println("Dum da dum, inside try...");
}catch(IOException e){ // Nothing throws IOException
}
}
}

/Casper

James Iry

unread,
Aug 19, 2009, 9:40:29 AM8/19/09
to java...@googlegroups.com
On Wed, Aug 19, 2009 at 1:03 AM, Peter Becker <peter.becker.de@gmail.com> wrote:

Interestingly Java's generics allow the dual construction on interfaces:

public <T extends Interface1 & Interface2> void someMethod(T param) {...}

Yeah, you can do intersection types in generics.  But you can't write

Interface1 & Interface2 foo() {...}

Interface1 & Interface2 x = foo();

Also, note the syntax is different when you create a new type in that intersection

class Bar implements Interface1, Interface2

Java is maddening with its irregularity.


I really like the idea of having the anonymous unions/joins and
considering that the resulting type system should be a complete lattice
they sound manageable to me -- both for the compiler and the human
reader. Does anyone know reasons why no language seems to have this feature?


I honestly don't know.  I'm not aware of any languages with that kind of union type.  Certainly with Scala's pattern matching it would be a prime candidate for re-extracting union types, but even it doesn't have them.

Reinier Zwitserloot

unread,
Aug 19, 2009, 9:49:32 AM8/19/09
to The Java Posse
I may have mentioned it before, but due to very complex reasons I
won't go into here, "catching a checked exception that cannot be
thrown" will most likely become a warning and not an error in java 7.
So, Jess, your #1 gripe may be about to be resolved*.

*) As there isn't an umbrella JSR, let alone some sort of official
list of java 7 changes, this isn't set in stone. It is, however, a
likely requirement in order for a proposal on the coin shortlist
that's been unanimously well accepted to be backwards compatible. We
all know how anal sun gets about backwards compatibility, so for once
you may keep your hopes up.

On Aug 19, 1:58 pm, Jess Holle <je...@ptc.com> wrote:
> I see this as an important change quite apart from the current debate.
>
> Catching an exception that cannot be thrown should be a *warning* not an
> error.
>
> I'm sick of having code stop compiling because someone stopped throwing
> a checked exception!  That should *not* be a breaking change.  There is
> justification for a warning -- something changed that you might want to
> look into and clean up accordingly -- but there's no cause for an error.
>
> This would be my #1 gripe about javac -- bar none.
> //

James Iry

unread,
Aug 19, 2009, 9:57:45 AM8/19/09
to java...@googlegroups.com
I don't follow.  Union types don't seem particularly structural to me.  They're the disjunction of other types, and if the other types are nominative then so is the union of them.  A type like String | Integer contians all expressions that are Strings or Integers. The idea would be that you can write the followig.  Here I'm borrowing a touch of Scala syntax to allow switch on runtime type and use | to indicate disjunction of types.

void foo(String | Integer argument) {
 switch(argument) {
   case s : String => "It was a String " + s
               break;
   case i : Integer => "It was an Integer " + i
 }
}

The types of actual arguments would be checked statically.  The type system would allow foo("hello") and foo(42) but would not allow foo(false).  For backward compatibility, the argumenttype could be erased to the least upper bound (in this case Object) in the bytecode. 

Similarly, you could write

String | Integer foo(Boolean flag) {
   if (flag) return 42;
   else return "hello";

Ben Schulz

unread,
Aug 19, 2009, 10:36:37 AM8/19/09
to The Java Posse
That's what I was refering to as having to check the runtime type. I
don't feel like you gained much in your sample, you could just replace
"String | Integer" with Object and add a "default: throw new
AssertionError();". Obviously you gained type safety, but it would be
much more useful if unions were structural:

public static void closeSilently(InputStream|OutputStream|Reader|
Writer|Channel preCloseable) {
try {
preCloseable.close();
} catch(IOException e) {}
}

With kind regards
Ben

James Iry

unread,
Aug 19, 2009, 11:18:19 AM8/19/09
to java...@googlegroups.com
On Wed, Aug 19, 2009 at 7:36 AM, Ben Schulz <ya...@gmx.net> wrote:

 
don't feel like you gained much in your sample, you could just replace
"String | Integer" with Object and add a "default: throw new
AssertionError();". Obviously you gained type safety,

Isn't that kinda the point of a type system?  :-)   I've pushed the constraint that "argument" must be either an Integer or a String out of the documentation where only humans can get at it and into the type system where both humans and tools can understand it.

 
but it would be
much more useful if unions were structural:

public static void closeSilently(InputStream|OutputStream|Reader|
Writer|Channel preCloseable) {
   try {
       preCloseable.close();
   } catch(IOException e) {}
}

Agreed, that would be more useful than only having type dispatch.  But union types can join types that share virtually no common structure, so type dispatch is a must to make union typing useful while computing  a common structural type is "merely" very nice for cutting down on code repetition.  In a way you can see this stuff as generalizing what Java already does with checked exceptions and catch blocks.  Several catch blocks in a series form a type dispatch mechanism.   It would be nice if unions of exception types could be caught and dealt with using common code, but the exception system would be unusable if you couldn't dispatch on individual exception types.

Jess Holle

unread,
Aug 19, 2009, 12:12:00 PM8/19/09
to java...@googlegroups.com
Thanks for the info.

That would be *great*.

Ben Schulz

unread,
Aug 19, 2009, 12:14:17 PM8/19/09
to The Java Posse
> Obviously you gained type safety,
>
> Isn't that kinda the point of a type system?  :-)

I suppose, but for me it's more about why I should write down the
types. If we asked Gilad Bracha, he'd probably say it's a bad idea
because they restrain your thinking. Me, I say it's good because the
compiler can verify that all messages sent are understood by their
receivers. Structural unions would get me much farther in that
direction and that's where I want to go. If I understand it correctly
(and I can only hope in this case) I would not need to write down any
types if higher-order unification was decidable. Wouldn't that be
nice?

With kind regards
Ben

phil swenson

unread,
Aug 19, 2009, 1:53:44 PM8/19/09
to The Java Posse


On Aug 18, 4:48 pm, Peter Becker <peter.becker...@gmail.com> wrote:
> phil swenson wrote:
> So you are saying it is better to quietly change behaviour than to make
> a change to an API that breaks source compatibility? I certainly would
> not agree to that.

So every API written in every other language ever written in the
history of software got it wrong eh?
Exceptions mean something went wrong. You will detect this when it
happens (testing, iterative dev). And again, it's almost always
because of a bug or something else you can't gracefully handle (like
server down as you mention). If you decide to handle one of these
conditions, that's fine - but usually it's better to let the condition
bubble up to the top thread an notify the user/email the admin.


> Sorry, but I call BS on that. SQLExceptions get thrown when the DB
> server is down or in trouble, when the network has issues and possibly
> other reasons that you do not encounter in test environments, so your
> testing won't help.

Ok, I modify my original claim of "it's almost always a bug" to "it's
almost always a bug or a condition that you can't do anything about in
code". If your db server is down, all you can do it manually
intervene and get the thing running again. If you are in a scenario
where data loss is unacceptable (where you would do a catch/retry),
then you still need to handle runtime exceptions anyway.

The key is to make the exception known and notify someone. Checked
exceptions usually have the opposite effect. You can say "that's
because people don't use them correctly." Sure, but I still haven't
seen anyone who does use them correctly. It's too much of a PITA.




Lorenzo

unread,
Aug 19, 2009, 2:35:55 PM8/19/09
to The Java Posse
Hi all,

A few days ago I ran into an interesting article about Java Exceptions
Handling on the Oracle technology website:

http://www.oracle.com/technology/pub/articles/dev2arch/2006/11/effective-exceptions.html

It covers checked/unchecked exceptions and multi-tier hints.

Lorenzo

Reinier Zwitserloot

unread,
Aug 19, 2009, 2:45:14 PM8/19/09
to The Java Posse
disjoint types are structural in that you weaken the namespacing of
members.

Members are only namespaced by virtue of their container. So lets say
I do this (I apologize in advance for the cliché factor of this
example):

public class com.ren.Gun {
public void shoot() { System.out.println("BANG!"); }
}

public class com.stimpy.Camera {
public void shoot() { System.out.println("Smile!"); }
}

public void pointAndClick(Gun | Camera object) {
object.shoot();
}


should that be legal code? I'd argue no - the fact that both Gun and
Camera have a 'shoot' method is a pure coincidence. They aren't the
same thing at all. Instead, I'd say that such a disjoint type should
only have the members of the common superclass (in this case, that
would be as if 'object' is an Object and no more), with the caveat
that you can pattern match on it. If you indeed cannot call shoot() on
the union of Camera and Gun, it's 100% nominal in my book.

Peter Becker

unread,
Aug 19, 2009, 6:21:40 PM8/19/09
to java...@googlegroups.com
Reinier Zwitserloot wrote:
> Replies inline. The problem is simply this: You think I was trying to
> argue against checked exceptions in general. I wasn't. I was arguing
> that the checked exception system isn't perfect, and therefore
> programmers need to be given a tool to say to the compiler: I know
> better than you. Stop whining.
>
> More specific arguments follow below, inline.
>
> On Aug 19, 12:56 am, Peter Becker <peter.becker...@gmail.com> wrote:
>
>>> Runnable does not let you throw Exceptions. Anyone up for defending
>>> this grievous API design? The amount of annoyance that this is caused
>>> me is almost limitless.
>>>
>> Where would that exception go?
>>
>
> The same place the RuntimeExceptions thrown by the runnable go. Your
> argument only makes sense if Runnable was precluded from throwing -any
> and all- exceptions. That's not true. What possible use is there for
> someone invoking a Runnable (which after all stands for: I have no
> idea what this does, other than run... something...) - to
> differentiate between checked exceptions and unchecked exceptions? The
> thing threw an exception. It doesn't matter what kind of exception was
> thrown.
>
> So, for Thread, that would be: The exception handler of that thread.
>
Fair enough. I keep forgetting about runtime exceptions, that's why I
like the checked ones :-)

[...]


>> If you just allow any exception to go through (e.g. by letting the
>> methods throw Exception on the API level), programmers will forget to
>> handle things they could handle.
>>
>
> Idiots write idiot code. But, okay, I'll roll with your argument: Then
> why isn't there a mechanism to escape it? Why can't I say: Nono,
> compiler, I did not forget anything, this is what I want. Shut your
> yap. You're not really going to argue with me that there is no
> inconvenience at all here, right?
>

The problem I see is that someone on a lower layer might have done this
and the guy on the layer above is not aware of it. I know you will
counter with the argument that the alternative is bad catches, and I
agree to some extent. But those catches you describe (the
e.printStackTrace() and similar) are known to be bad, adding a mechanism
to the language makes it look much more legit. Of course the new
RuntimeException(e) is much better, but I don't think it is a general
solution either.


>
>
>>> InputStream.close() throws IOException. Nuff said.
>>>
>> That only proves that exceptions are used badly in the JDK.
>>
>
> That "only" proves? The JDK abuses checked exceptions - That's a
> pretty big deal! That's the whole point! That's why the language needs
> an escaping mechanism.
>

It doesn't seem right to add language features to deal with crappy
library design.


> The further damage caused by bad coders abusing the escaping mechanism
> are, in my opinion, much, __much__ smaller than the potential further
> damage that would no longer becaused because the mechanism is
> available. The occasional explicitly supressed checked exception that
> should have been handled is far less of a crime than code littered
> with this abomination:
>
> try {
> something();
> } catch ( IOException e ) {
> e.printStackTrace();
> //TODO Eclipse auto-generated this. The programmer never looked at
> it again, logging to system.err is just about the worst thing you
> could do here, and the original programmer only hit quickfix-add try
> catch block because he couldn't throw it onwards because he's
> implementing a servlet, or a runnable.
> }
>
> Sure, an idiot coded that. But we're all idiots some of the time, and
> you yourself put 'idiots exist' on the table as a legal line of
> reasoning.
>

What you are proposing seems to me like making a mediocre solution easy
to avoid people doing the really bad ones. Call me an idealist, but I
don't really like that.

Just think of the problem one layer above the one that may use the
sneaky throws: you might get some methods you call that pass the
IOException to you, some might do what I consider right and chain it
with their own checked exception and other just do the sneaky throw. To
figure out what's happening I really need to know the internals of each
method down to the bottom. The alternative is catch(Exception).

Admittedly the problem is already there since Java has both checked and
unchecked exceptions.

>>> FilterInputStream and FilterOutputStream's methods throw IOException,
>>> but if I feed it a ByteArrayInputStream, or I let it filter into a
>>> ByteArrayOutputStream, then an IOException can never happen.
>>>
>> Which could be solved by having safe and unsafe versions of the interface.
>>
>>
>
> Do you realize how much code duplication that would require? Exactly
> _BECAUSE_ you can't circumvent checked exception checking, you'd
> actually have to copy/paste every method. I cannot put into words the
> insanity of a system that would _require_ you to copy/paste vast
> tracts of code just to satisfy a system that is principally designed
> to help code maintainance. Talk about bass ackwards. In practice, you
> would most likely implement this by.... employing a sneaky throw hack.
> I can scarcely imagine a better case for enshrining sneaky throwing
> into the JLS, than this line of reasoning.

No implementation would be duplicated, the safe version could be a
subtype of the unsafe one. Not too many interfaces will face that
problem. To me it seems much better than not distinguishing.

Peter

It is loading more messages.
0 new messages