Reducing "exception is never thrown in body of corresponding try statement" Error to a Warning

Remi Forax forax at univ-mlv.fr
Mon Oct 21 22:22:36 UTC 2019


Hi Mike,
as an advocate of the idea of removing checked exceptions from Java, there is a simple solution:
defines your interface in Kotlin (or Scala), and selectively uses the annotation @Throw on the exception you want to keep to be compatible with the Java classes that implements that interface.

and i strongly believe that if we want to be backward compatible and allows to change the list of checked exceptions of an abstract method, the only solution is to get ride of the idea of checked exceptions in the JLS. All other half measures do not work because you have client checking rules (the ones you want to make more flexible) and the overriding checking rules (the ones Brian is talking about) that sandwich you from both ways.

Rémi

----- Mail original -----
> De: "Mike Duigou" <openjdk at duigou.org>
> À: "jdk-dev" <jdk-dev at openjdk.java.net>
> Envoyé: Lundi 21 Octobre 2019 00:36:42
> Objet: Reducing "exception is never thrown in body of corresponding try statement" Error to a Warning

> Hello all;
> 
> As part of my Oracle CodeOne talk "Exceptions 2020" I made two proposals
> for improving Java exceptions. One of the proposals was to remove the
> compile time error produced when and exception is caught that is not
> thrown by the enclosed statements. Specifically I am proposing the
> removal of the following section from JLS 11.2.3
> 
>     "It is a compile-time error if a catch clause can catch checked
> exception class E1
>      and it is not the case that the try block corresponding to the
> catch clause can
>      throw a checked exception class that is a subclass or superclass of
> E1, unless E1
>      is Exception or a superclass of Exception."
> 
> The advantage of removal of this rule is that removal allows API authors
> to better document the actual exceptions thrown by constructors and
> methods. Vestigial or inaccurate throws specifications can be eliminated
> without "breaking" calling code. This makes it easier to evolve the API
> by narrowing (including to empty), the exception specification of method
> without impacting existing code which uses the API.
> 
> To allow application authors to clean up dead code an equivalent warning
> would still be provided and probably should be encouraged by the JLS
> specification. The warning would alert them that the catch clause will
> not be executed.
> 
> As an API author I have been frustrated many times by being unable to
> reduce or remove a method's exception specification without causing
> compatibility issues for my users and I have also been frustrated when
> libraries did choose to alter their method exception specifications and
> "broke" my code which caught the no longer thrown exceptions. Does this
> seem like a feature/change worth pursuing?
> 
> Cheers,
> 
> Mike
> 
> The changes to javac needed to accomplish this change are quite simple:
> 
> diff --git
> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
> index 0c1fead9a4..f7793d0605 100644
> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
> @@ -1271,7 +1277,7 @@ public class Flow {
>              } else if (!chk.isUnchecked(pos, exc) &&
>                      !isExceptionOrThrowable(exc) &&
>                      !chk.intersects(exc, thrownInTry)) {
> -                log.error(pos, Errors.ExceptNeverThrownInTry(exc));
> +                log.warning(pos, Warnings.ExceptNeverThrownInTry(exc));
>              } else {
>                  List<Type> catchableThrownTypes =
> chk.intersect(List.of(exc), thrownInTry);
>                  // 'catchableThrownTypes' cannnot possibly be empty -
> if 'exc' was an
> diff --git
> a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
> index 1f29df0704..e29b5583e4 100644
> ---
> a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
> +++
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
> @@ -533,10 +533,6 @@ compiler.err.error.reading.file=\
>  compiler.err.except.already.caught=\
>      exception {0} has already been caught
> 
> -# 0: type
> -compiler.err.except.never.thrown.in.try=\
> -    exception {0} is never thrown in body of corresponding try
> statement
> -
>  # 0: symbol
>  compiler.err.final.parameter.may.not.be.assigned=\
>      final parameter {0} may not be assigned
> @@ -2019,6 +2015,14 @@ compiler.warn.unchecked.generic.array.creation=\
>  compiler.warn.unchecked.varargs.non.reifiable.type=\
>      Possible heap pollution from parameterized vararg type {0}
> 
> +# 0: type
> +compiler.warn.except.never.thrown.in.try=\
> +    exception {0} is never thrown in body of corresponding try
> statement
> +
>  # 0: symbol
>  compiler.warn.varargs.unsafe.use.varargs.param=\
>      Varargs method could cause heap pollution from non-reifiable
> varargs parameter {0}


More information about the jdk-dev mailing list