Compile error in multi type catch block with Java 11, runtime error with Java 17
S A
simeon.danailov.andreev at gmail.com
Wed Mar 29 20:15:57 UTC 2023
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
The bug-fix was done for: https://youtrack.jetbrains.com/issue/IDEA-297529
A similar bug was opened for ecj:
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://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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/serviceability-dev/attachments/20230329/c86b814d/attachment.htm>
More information about the serviceability-dev
mailing list