Stuart,
Stuart Ballard wrote:
Tim Ellison <t.p.ellison <at> gmail.com> writes:
Stuart: is there some way to avoid JAPI taking inherited API signatures
into account when doing the diff? kinda like the javadoc tool.
This is something of a Japi FAQ (I should probably put together a Japi FAQ page
somewhere now that it's no longer the case that pretty much everyone using Japi
is on the Classpath list ;) ).
The answer is no, it doesn't do this, and I'm not going to implement it. The
reason is that whether a method is overridden or not is *not* part of the public
API. Javadoc documents it, sure, but that's not really sufficient to say whether
it's part of the API or not - it's quite likely it was simply easier to write
Javadoc that way (so it didn't have to go and find the doc comments in the
superclass's source file, etc).
The rules of binary compatibility say that moving a method up or down the class
hierarchy is a completely compatible change.
A method may be overridden, or not, purely for performance reasons and the
behavior could be completely identical. For example, LinkedList.subList is not
documented as being overridden, but if it's not, that guarantees that the
iterator() method will always be at least O(N) where N is the startIndex that
the sublist was created with. An overridden LinkedList.subList method could hang
on to the start and end nodes of the list and provide an O(1) implementation of
iterator(). As long as some effort was taken to ensure that serialization stayed
compatible, there's no reason why a Free runtime shouldn't do that optimization
even if Sun doesn't.
I've also heard of cases where Sun documents a method as being overridden even
though as far as any testing can determine, all it does is call super. There
should be no obligation for any Free runtime to duplicate this inefficiency.
It's also possible to implement a method that needs changed behavior in a
subclass by making the superclass delegate some parts of its behavior to
non-public methods, so the superclass method is unchanged but the subclass just
overrides the non-public methods (obviously, this only works if the subclass is
in the same package, but that's pretty common).
Finally, it's possible (albeit unlikely) that even if there *was* an apparent
need to override a method in a subclass because it has different behavior, there
might be some weird optimization-related reason why somebody might want to
actually write it as "if (this instanceof Whatever)" in the superclass. I can't
see why that would happen, but if someone did that and got all the behavior
right, they shouldn't be penalized for it in Japi.
Most of above is true and has good reason, but as a practicer trying to
implement a RI compatible class library, I still feel strongly that the
method override information has its value, maybe a most common example
is equals(Object), most classes don't override this method and only call
j.l.Object's, but others DO has their own criteria, it's very reasonable
to just remind programmer to implement this method, otherwise it will
introduce serious compatibility issue.
Just as a proposal, if you still feel that override difference is
another story with common difference, how about to separate them into
another category, similar with Compiler's warning, which at least can be
as reference to programmer, and this information even can be switched on
only if some user want to check the difference more *strictly*.
Basically, Japi's business is to test the coverage of the API, and it's a
fundamental design decision that Japi will *not* be testing implementation
details. I've done quite a lot of work fixing bugs where implementation details
inadvertently get exposed in the Japi results and if I find any more I'll fix
them too.
I think this is *extremely* important because, among other things, it's the
*only* reason I feel legally secure in distributing Japi files for the JDK. As
long as they only contain functional information necessary for interoperability,
they're uncopyrightable. If they start exposing copyrightable implementation
details, they become derived works of the JDK, and illegal to distribute (or,
technically, to even create in the first place). And potentially so do the
results of the comparisons. And if you then use those comparisons to make
decisions on what to implement in Harmony, it jeopardizes Harmony's cleanroom
status too. (IANAL; the people who actually decide whether legal risks are
acceptable might think this isn't actually a problem for Harmony, but *I* don't
want to be responsible for it ;) )
The right way to ensure that you've overridden all the right methods is to test
the *behavior* of those methods. Obviously this is a lot more work than a simple
automated run via Japi or equivalent, but it's the only way to get meaningful
results.
It is definitely the right way, but maybe not the most practical one.
Still the example of equals(), do we need a testEquals for every single
class? or do we still need to check the JavaDoc one by one to find
difference on this method? why not the tool just give some warning to
some possible incompatible?
Obviously since Japi is Free Software I can't prevent others from making a
version that does this, but I hope I've shown why I think it would be a bad
idea.
There is another issue of JAPI, pls. correct me if I'm wrong, seems the
*final* information is also ignored. I also think this difference of
method signature is a compatibility issue which could not be overlooked,
because the spec writer might have consider very carefully about which
methods can be overridden and which should be immutable. Comments?
Stuart.
--
Paulex Yang
China Software Development Lab
IBM