Managed exceptions: leveraging Java modules with the view to making a Java checked exception handling mechanism work as it should.

Owen Thomas owen.paul.thomas at gmail.com
Thu Nov 4 11:41:53 UTC 2021


Hello Java SE Platform JSR Expert Group.

I had recently canvassed an idea with a few people, and in an attempt to
give it a larger audience perhaps among others who have clout in the future
shape of Java SE, I have been led to make a disclosure here. You will find
the short conversation with someone from Oracle who prompted me to write to
this group at the bottom of this email.

I want to keep this email short, but I still wish to convey my prime
reasons for making this disclosure. I will hope to do this by copying and
slightly modifying the use case that I first disclosed among the recipients
I alluded to above. Before I disclose the use-case, I will introduce the
idea through a preamble. I'm not totally au fait with modules as I haven't
yet been compelled to draw on them in my code, but, I've been a programmer
for a long time, and so I believe I have a fair estimation of what a Java
module is.

I hope you find this email sufficiently brief.

So, Java's checked exception mechanism has been maligned for being
inadequate. I think it is unfortunate that checked exceptions have, with
hindsight, turned out not to deliver on their promise when introduced long
ago. Developers now tend to avoid using checked exceptions - many (myself
included) often find themselves in the situation where the best way to deal
with a checked exception is to wrap it in a runtime exception or another
checked exception and throw that exception. Hopefully, one retorts to one's
self, it will be caught and dealt with later on.

With the introduction of Java modules in SE 9, new ways of grouping code
into functional units was introduced. I think that the handling of
exceptional programmatic behaviour can also be modularised with significant
benefit to the developer. Moreover, I think the reimagination of checked
exceptions in the context of modularisation might ultimately be seen to
provide a significant help for developers in writing robust code.

... perhaps.

First, consider the addition of an abstract exception class in the Java SE
API. Call it, say, ManagedException. Descendents of this class behave like
any other checked exception, with perhaps a few caveats - some of which
will be covered in what follows, and others may be gleaned by further
discussion among this group. A module's descriptor file can indicate which
descendents of ManagedException (never the ManagedException itself) are
"thrown", "caught", or "ignored" in the associated module.

Next, imagine this scenario. Hopefully, this use case describes what
happens when an exception that extends ManagedException  is "ignored". If
you get the use-case I am describing here, you can probably imagine what
might happen in other scenarios.

So, you are developing a library that depends on another library. This
other library declares in a module descriptor that a particular exception
is "thrown". This module descriptor has to do this because this exception
extends ManagedException, and at least one method in this module declares
that it throws this exception.

You're in charge of the module descriptors in your library, and so in your
library, you have a module governed by a descriptor which says that the
exception thrown from the module defined above is "ignored". You have to
care about what your module does with this exception because at least one
of the methods defined in your module calls at least one of the methods
defined in the module above. When you call any method declared within the
above defined module from your module, your calling method cannot either
catch this ignored exception in your code, nor declare that it throws this
exception.

Importantly, I think that the checked behaviour of such an exception has
been preserved. Modules defined by others that call one or more methods
defined in yours would likewise have to do something with this ignored
exception just as you have done. A developer calling methods in your module
would have to declare in their module descriptor what they are going to do
with the exception that you have ignored: either to declare that they are
"ignored" or "caught"... another use case.

So, you have "ignored" the fact that a method you call throws a particular
extension of the class ManagedException. Your methods cannot catch, or
declare that they throw this exception because you said in your module's
descriptor that you wanted this concern abstracted away for you. You have,
however, passed this concern onto anyone who might use your module. Others
are free to do with their module as you have done with yours, but they
still have to do something to address the fact that this managed exception
you have elected to ignore has been passed through your module to theirs.


*A small, and I think favourable twist, unlike checked exceptions, is that
one might be able to, for instance, have an overridden Object.equals()
actually declare that it throws a managed exception. This would perhaps
slightly and temporarily modify the signature for Object.equals() which has
been overridden in some module where a particular managed exception was
"thrown" until the exception was handled somewhere in another dependent
module where the exception was "caught". I can't at this moment see why
this would be a problem; I see it as something I would like.*

Perhaps, if another developer's library implements a mechanism called
directly from Thread.run(), any "ignored" exception will just behave like
an unchecked exception. Perhaps however, it would be more in-keeping with
the original intentions of the checked exception mechanism that a compiler
error would be issued, and hence I like this latter scenario better.

I think this change is backwards compatible, and other languages like
Kotlin that use the JVM would remain unaffected. Perhaps a module that
makes use of the managed exception feature may complicate things for a
Kotlin coder. However, Kotlin and other languages might, at some time in
the future, decide that managed exceptions are a good thing for their
language to take notice of them too.

So there you go. I have submitted this email to this group in good faith. I
hope you find it to be valuable in some way. I am more than willing to
engage further in a discussion of this topic. Please note that I am not a
member of this expert group, so I cannot subscribe to this list.

  Owen.

---------- Forwarded message ---------
From: Owen Thomas <owen.paul.thomas at gmail.com>
Date: Thu, 4 Nov 2021 at 08:30
Subject: Re: Submitting and idea for consideration?
To: Harold Ogle <harold.ogle at oracle.com>


Thanks Harold. :)

On Thu, 4 Nov 2021 at 06:25, Harold Ogle <harold.ogle at oracle.com> wrote:

> Owen:
>
>
> Thanks for reaching out to us! Ideas for enhancements to specifications
> should be sent to the groups working on those particular specifications.
>
> The next iteration of Java SE is being developed as JSR 393
> (https://jcp.org/en/jsr/detail?id=393), and the method described on that
> page for reaching out to the group is to send mail to the
> java-se-spec-comments list
> (https://mail.openjdk.java.net/mailman/listinfo/java-se-spec-comments).
>
>
>      Best regards,
>
>           Harold
>
>           JCP Program Management Office
>
>
>
> On 11/3/2021 3:00 AM, Owen Thomas wrote:
> > Hi.
> >
> > If I had an idea for an enhancement to the Java SE language spec, API,
> > and possibly the JVM, would this be the right place to give my ideas a
> > hearing to deliberate this possibility?
> >
> > What steps might I take next?
> >
> > Thanks,
> >
> >   Owen.
>


More information about the java-se-spec-comments mailing list