RFR (S) 8151223: String concatenation fails with implicit toString() on package-private class
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Mar 9 10:42:04 UTC 2016
I'm not 100% sure about the missing links - here's what Chapter 13 says:
"Changing the direct superclass or the set of direct superinterfaces of
a class type will not break compatibility with pre-existing binaries,
provided that the total set of superclasses or superinterfaces,
respectively, of the class type loses no members."
Which seems to imply that it is ok to change the supertypes if subtyping
relationships are preserved - that is, if S is a supertype of C, S must
continue to remain so even in the updated hierarchy.
Under those assumptions what the current implementation does doesn't
look all that terrible, and I think (as pointed out yesterday) the worst
thing can happen in a binary compatible scenario is that you end up
picking a type that is not the sharpest possible - oh well.
If you do have missing links, then you have a binary incompatible change
(i.e. the set of supertypes is not preserved), and if you have a binary
incompatible change, what exactly are we trying to save here? There are
already millions of other things that can fail as a result of a missing
link - as explicitly pointed out in the spec:
"If a change to the direct superclass or the set of direct
superinterfaces results in any class or interface no longer being a
superclass or superinterface, respectively, then linkage errors may
result if pre-existing binaries are loaded with the binary of the
modified class. Such changes are not recommended for widely distributed
classes."
So, why should this case be treated specially?
Maurizio
On 09/03/16 09:53, John Rose wrote:
> Accessibility of the chosen class is only part of the headache you are signing up for.
>
> Java binary compatibility rules also allow classes to change their super type hierarchy over time.
>
> So when you search up the super chain you are traversing links that may not be present when the code is run. You are getting static answers to questions about type relations which may have changed when the code runs. This is one of JLS Chapter 13's favorite tricks. You do not want it as your enemy.
>
> Basically, any static query done in javac has to be looked at with skepticism: It can change, if the answer to the query does not come from either the current compilation unit, or else from the Java language runtime selected by the "-target" option of javac.
>
> (Remi, this is why java.lang is special. The Groovy compiler is welcome to make static assumptions about groovy.lang or whatever, but javac binds only to java.lang.)
>
> My specific recommendation is not to ask questions with non-local answers in the static analysis of string operands. Fail up to Object, or (if you can and you wish) to a java.lang type.
>
>
> HTH
> — John
>
> ----- Original Message -----
> From: aleksey.shipilev at oracle.com
> To: john.r.rose at oracle.com, forax at univ-mlv.fr
> Cc: compiler-dev at openjdk.java.net
> Sent: Tuesday, March 8, 2016 12:53:09 AM GMT -08:00 US/Canada Pacific
> Subject: Re: RFR (S) 8151223: String concatenation fails with implicit toString() on package-private class
>
> On 03/08/2016 05:34 AM, John Rose wrote:
>> The more cleverly we use static information when generating
>> bytecodes, the more murky will be our binary compatibility story. I
>> suggest you rely mainly on locally available metadata (caller class
>> and its nest) and on stable packages (java.lang). Any uncertainty
>> should send the argument type all the way to Object. Dynamic type
>> profiling will pick up some of the dropped bits and we won't have
>> binary compat. puzzles to solve down the road. Like the present bug.
> Not really sure what you are suggesting to do right now, John.
>
> I think sharpening to the most specific accessible class is okay,
> because JLS Chapter 13 "Binary Compatibility" clearly points out that
> changing the visibility of classes/members to less access may be binary
> incompatible. IOW, once you compiled against an accessible class, it is
> a maintainers' headache to preserve compatibility.
More information about the compiler-dev
mailing list