RFR (S) 8151223: String concatenation fails with implicit toString() on package-private class

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Mar 14 10:29:02 UTC 2016


I can find two pieces of text that would seem to rule out the 
accessibility change that you describe:

JLS, 14.4.3: public classes:

"Changing a class that is not declared public to be declared public does 
not break compatibility with pre-existing binaries.

If a class that was declared public is changed to not be declared 
public, then an IllegalAccessError is thrown if a pre-existing binary is 
linked that needs but no longer has access to the class type; such a 
change is not recommended for widely distributed classes."

And, JLS, 15.12.4.3. Check Accessibility of Type and Method:

"let T be the qualifying type of the method invocation (§13.1 
<https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1>) and 
let m be the name of the method as determined at compile time 
(§15.12.3). [...] If either T or |m| is not accessible, then an 
|IllegalAccessError| occurs (§12.3 
<https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.3>)."

So, the first rule tells us that restricting accessibility of classes 
breaks BC - and the second rule explicitly mandates a VM implementation 
to throw IAE when an inaccessible qualifier is found on a method call.

If you have code like this:

class A {
    void m() { }
}

class B extends A {
   void test() {
      ((A)this).m();
   }
}

javac will emit a descriptor for the invokevirtual of the kind A::m.

Any access change to A which makes A inaccessible from B would then 
cause IAE at runtime, right?

Maurizio

On 10/03/16 23:42, John Rose wrote:
> Ok, now I mostly agree with Rémi and Maurizio. If a static search finds a super, we can assume that super will be present at runtime; so says Ch.13. The assumption of accessibility (of that chosen super) requires additional assurances which are (probably) in the spirit of 13 but not the letter.
>
> Here's my preference: Unless there is language in 13 guaranteeing accessibility of supers to clients (unlikely, but Maurizio can find it if it is there) then we should treat all supers as possibly-inaccessible (at runtime) except 1) those in the nest (compilation unit) of the class containing the indy call and 2) those in java.lang, which includes good old Object as a fallback. And 3) arrays thereof.
>
> Supers in the same package but not in the same nest, or in other package, if not java.lang, cannot be trusted to be accessible at runtime. Example: someone refactors a package-local super to be public and later refactors it non-public to reduce exports. Happens all the time.
>
> – John
>
> On Mar 9, 2016, at 6:17 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>
>>> provided that the total set of superclasses or superinterfaces,
>>> respectively, of the class type loses no members.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20160314/1d912a16/attachment.html>


More information about the compiler-dev mailing list