Late change to JEP 433

Remi Forax forax at univ-mlv.fr
Mon Nov 14 22:23:01 UTC 2022


Does someone has done the work to check if there are a few?, some?, a lot? of codes that catch IncompatibleClassChangeError in the wild ?

Because replacing a exception by another usually leads to subtle bugs, especially when an Error which is replaced by an RuntimeException.
Sadly catch(RuntimeException) / catch(Exception) are the usual trouble makers.

Rémi

----- Original Message -----
> From: "Gavin Bierman" <gavin.bierman at oracle.com>
> To: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Sent: Monday, November 14, 2022 1:38:46 PM
> Subject: Late change to JEP 433

> Dear Experts,
> 
> As we put the final polish on features for JDK20, we noticed that we have an
> opportunity to make a very small breaking change (as part of the preview
> feature) to simplify our lives. I’m writing to see what you think.
> 
> tldr: A switch expression over an enum class should throw MatchException rather
> than IncompatibleClassChangeError if no switch label applies at runtime.
> 
> Details:
> 
> When we introduced switch expressions, we opted for a design where the switch
> body had to be exhaustive. When switching over an enum type, a switch body with
> case labels supporting all the enum constants for the enum type is considered
> exhaustive, meaning a default clause is not needed.
> 
> However, there is a possibility that the enum class is changed after compilation
> of the switch expression, and a new enum constant added. Then when executing
> the switchexpression, no label would apply.
> 
> The question we faced in JDK14 was what to do at this point. We decided on
> IncompatibleClassChangeError as that was a pre-existing exception that was
> generally understood by developers as a signal that things have got out of sync
> and re-compilation is needed.
> 
> Back to the present day, with the support of pattern switches, we can now write
> switches over a sealed type. When switching over a sealed type, a switch body
> with case labels with type patterns matching all the permitted subclasses is
> considered exhaustive, meaning a default clause is not needed.
> 
> If the sealed hierarchy has been changed after compilation of the switch, it is
> possible that when executing the switch that no label would apply. In this case
> we have settled on throwing a MatchException.
> 
> Throughout our design process, we have noticed the connection between enum
> classes/enum constants and sealed class/permitted subclasses – they are
> essentially the same thing up the term/type hierarchy. Moreover, in a future
> release, we plan to support case labels with a mix of sealed class type
> patterns and enum constants.
> 
> But we now have an inconsistency - one throws IncompatibleClassChangeException
> in a bad situation and the other MatchException which will make this future
> development almost impossible. We need these cases to throw the same exception:
> MatchException. So we propose to make the small breaking case to the language
> that switch expressions over enum classes throw MatchException should no switch
> label apply in the switch body.
> 
> People who deliberately change their enum classes by adding new constants, and
> do not recompile their switches over this enum class, and rely on this throwing
> ICCE will notice this breaking change. We think this is a vanishingly small set
> of developers. The vast majority of developers, on the other hand, will thank
> us for this unification, especially if it enables other new features down the
> road.
> 
> What do you think?
> 
> Thanks,
> Gavin


More information about the amber-spec-experts mailing list