<div dir="ltr">Hi all,<br><br>could someone clarify the following difference in javac behavior between Java 11 and Java 17? Which one is correct?<br><br>There are two source files:<br><br>package p;<br>public class Exceptions {<br>    private static class E extends Exception {<br>        public void m() { }<br>    }<br>    public static class E1 extends E {}<br>    public static class E2 extends E {}<br>}<br><br>package q;<br>import p.Exceptions;<br>import p.Exceptions.*;<br>public class Test {<br>    public static void main(String[] args) {<br>        try {<br>            if (false) { throw new E2(); }<br>            throw new E1();<br>        } catch (E1 | E2 e) {<br>            e.m(); // javac 11: ...defined in an inaccessible class...<br>        }<br>    }<br>}<br><br>Compiling with Java 11 results in an error:<br><br>q/Test.java:12: error: E.m() is defined in an inaccessible class or interface<br>            e.m(); // javac 11: ...defined in an inaccessible class...<br>             ^<br>1 error<br><br>Compiling with Java 17 doesn't result in an error, but running the code results in a runtime exception:<br><br>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')<br>        at q.Test.main(Test.java:12)<br><br>The difference in behavior between Java 11 and Java 17 is probably introduced with: <a href="https://bugs.openjdk.org/browse/JDK-8264696">https://bugs.openjdk.org/browse/JDK-8264696</a><br><br>The bug-fix was done for: <a href="https://youtrack.jetbrains.com/issue/IDEA-297529">https://youtrack.jetbrains.com/issue/IDEA-297529</a><br>A similar bug was opened for ecj: <a href="https://github.com/eclipse-jdt/eclipse.jdt.core/issues/198">https://github.com/eclipse-jdt/eclipse.jdt.core/issues/198</a><br><br>It looks like John Vasileff has gone through the spec and asserts the Java 17 behavior is not expected, see comments:<br><br><div><a href="https://github.com/eclipse-jdt/eclipse.jdt.core/issues/198#issuecomment-1177897759">https://github.com/eclipse-jdt/eclipse.jdt.core/issues/198#issuecomment-1177897759</a></div><div><a href="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</a></div><br>> 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.<br>> <br>> In "6.6. Access Control":<br>> <br>> > 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.<br><br>Best regards and thanks,<br>Simeon</div>