Compile error in multi type catch block with Java 11, runtime error with Java 17
David Holmes
david.holmes at oracle.com
Wed Mar 29 23:37:59 UTC 2023
Hi,
This is the wrong mailing list for this issue - you want compiler-dev
for javac issues.
Cheers,
David
On 30/03/2023 6:15 am, S A wrote:
> Hi all,
>
> could someone clarify the following difference in javac behavior between
> Java 11 and Java 17? Which one is correct?
>
> There are two source files:
>
> package p;
> public class Exceptions {
> private static class E extends Exception {
> public void m() { }
> }
> public static class E1 extends E {}
> public static class E2 extends E {}
> }
>
> package q;
> import p.Exceptions;
> import p.Exceptions.*;
> public class Test {
> public static void main(String[] args) {
> try {
> if (false) { throw new E2(); }
> throw new E1();
> } catch (E1 | E2 e) {
> e.m(); // javac 11: ...defined in an inaccessible class...
> }
> }
> }
>
> Compiling with Java 11 results in an error:
>
> q/Test.java:12: error: E.m() is defined in an inaccessible class or
> interface
> e.m(); // javac 11: ...defined in an inaccessible class...
> ^
> 1 error
>
> Compiling with Java 17 doesn't result in an error, but running the code
> results in a runtime exception:
>
> Exception in thread "main" java.lang.IllegalAccessError: failed to
> access class p.Exceptions$E from class q.Test (p.Exceptions$E and q.Test
> are in unnamed module of loader 'app')
> at q.Test.main(Test.java:12)
>
> The difference in behavior between Java 11 and Java 17 is probably
> introduced with: https://bugs.openjdk.org/browse/JDK-8264696
> <https://bugs.openjdk.org/browse/JDK-8264696>
>
> The bug-fix was done for:
> https://youtrack.jetbrains.com/issue/IDEA-297529
> <https://youtrack.jetbrains.com/issue/IDEA-297529>
> A similar bug was opened for ecj:
> https://github.com/eclipse-jdt/eclipse.jdt.core/issues/198
> <https://github.com/eclipse-jdt/eclipse.jdt.core/issues/198>
>
> It looks like John Vasileff has gone through the spec and asserts the
> Java 17 behavior is not expected, see comments:
>
> https://github.com/eclipse-jdt/eclipse.jdt.core/issues/198#issuecomment-1177897759 <https://github.com/eclipse-jdt/eclipse.jdt.core/issues/198#issuecomment-1177897759>
> https://youtrack.jetbrains.com/issue/IDEA-297529/Wrong-compilation-error-reported-when-multi-type-catch-block-references-visible-method-from-invisible-type#focus=Comments-27-6280209.0-0 <https://youtrack.jetbrains.com/issue/IDEA-297529/Wrong-compilation-error-reported-when-multi-type-catch-block-references-visible-method-from-invisible-type#focus=Comments-27-6280209.0-0>
>
> > because, within the catch block, the type of `e` is `Exceptions.E`
> per the LUB algorithm in "4.10.4. Least Upper Bound". And, per "6.6.
> Access Control", `Exceptions.E` should not be accessible outside of
> `Exceptions`. The members of `Exceptions.E` should be unavailable.
> >
> > In "6.6. Access Control":
> >
> > > Otherwise, the member or constructor is declared private. Access is
> permitted only when the access occurs from within the body of the top
> level class or interface that encloses the declaration of the member or
> constructor.
>
> Best regards and thanks,
> Simeon
More information about the serviceability-dev
mailing list