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