JDK-8289980 : 14.20.3: Check access to the inferred type of a multi-catch exception
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 19
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2022-07-08
  • Updated: 2022-08-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_majorUnresolved
Related Reports
Blocks :  
Relates :  
Description
For multi-catches, 14.20.3 does not require an access check on the inferred type of the exception. In the program below, 14.20.3 just says "the type of e is the lub of E1 and E2", without regard for whether EBase is accessible at the point of the multi-catch.

    class Exceptions {
        private static class EBase extends Exception {
            public void m() { System.out.println("EBase::m"); }
        }
        public static class E1 extends EBase {}
        public static class E2 extends EBase {}
    }

    public class MultiCatchTest {
        public static void main(String[] args) {
            try {
                throwSomething();
            } catch (Exceptions.E1 | Exceptions.E2 e) {
                e.m();
            }
        }
      
        static void throwSomething() throws Exceptions.E1, Exceptions.E2 {
            throw new Exceptions.E1();
        }
    }

This program compiles without error, which is wrong, and runs without error, which is very wrong. The class Exceptions has a private member class EBase, which should be inaccessible from the body of a different class like MultiCatchTest. However, EBase is compiled to a top-level package-access class, so is accessible at run time for the exception handler in MultiCatchTest. Statically forbidding the exception handler from accessing EBase.m would sidestep the problem of infelicitous compilation (private member compiles to a non-private class) allowing illegitimate access.

The corresponding javac bug JDK-8289975 shows a similar example program, where class Exceptions is in a different package than class MultiCatchTest. The program there compiles without error, but gives an IAE at run time. Statically forbidding the exception handler from accessing EBase.m would sidestep the problem of inconsistent behavior between compile time and run time.
Comments
It would be unreasonably complicated to have lub (JLS 4.10.4) consider the accessibility of the type it computes. Accordingly, the exception parameter e has to continue being typed by lub as EBase, not Throwable or Exception. In and of itself, e being typed as EBase is fine -- maybe the catch body doesn't use e, or passes e harmlessly to a log(Object) method -- it's only if e is used as an EBase that a compile-time error should occur.
08-07-2022

I'll note that the exceptions in a multi-catch always have *some* accessible supertype, even if it is just Throwable. So while the e.m(); code should be problematic in the example, the "catch (Exceptions.E1 | Exceptions.E2 e)" need not be.
08-07-2022