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