On Tue, 6 Sep 2022 07:55:55 GMT, Markus KARG <d...@openjdk.org> wrote:
>> test/lib/jdk/test/lib/hexdump/HexPrinter.java line 1194: >> >>> 1192: byteOffset += size; >>> 1193: return size; >>> 1194: } >> >> This is an indication that overriding `transferTo()` in >> `BufferedInputStream` has potential compatibility impacts on its subclasses. >> Therefore I would suggest adding a check in >> `BufferedInputStream::transferTo` to only override the behavior if not >> subclassed. Something like: >> >> >> if (this.getClass() != BufferedInputStream.class) { >> // a custom subclass may have expectations on which >> // methods tansferTo() will call. Revert to super class >> // behavior for compatibility. >> return super.transferTo(out); >> } >> ... otherwise proceed with the new implementation ... >> >> >> Then you can revert the changes in this test. > > I do not see that it makes much sense to add such a safety means before I am > finished with the inspection of the subclasses. As you can see in this > example, it was pretty easy to fix it, and there are only few such subclasses > at all. So instead of preparing against possibly non-existing easyt-to-fix > problems, I prefer fixing the actual problems. They can only occur inside of > the JDK itself, as relying on any particular implementation inside of the JDK > by non-JDK classes simply would be a complete programming fault and *must* > get fixed. It's a well known behavior that overriding the`read(...)` method is sufficient to implement subclass behavior. This will no longer be the case if `transferTo(...)` no longer calls `this.read(...)` as it used to. There are many undocumented behaviors that have been depended on over the year - and though I agree with the sentiment that it's not a good idea to depend on undocumented behavior, this is one that is long standing, and mostly legitimate, especially for those classes that were coded before `transferTo` was added to `InputStream`. The issue here is that things would mostly work for those custom subclassed, up to the point where some unsuspecting code might call `transferTo`. This could lead to bugs that might become hard to diagnose, and of course would only be seen at runtime. As a point of comparison, look at what [JEP 425](https://openjdk.org/jeps/425) did to change the locking in `BufferedInputStream` (see how the lock object is used/initialized). How many classes of `BufferedInputStream` are there in the wild, outside of the JDK? How many of them have custom behavior implemented in `read`, that would be broken if `transferTo` no longer called `this.read`? If you're changing an observable behavior, you will need a CSR, you will need to evaluate the compatibility risk and justify it, you will need to write a Release Note to warn about the compatibility risk, so that custom implementations that have such a dependency can be changed to also override `transferTo`. The main question is whether the advantage of changing the behavior outweigh the risk of regression it might cause in subclasses. Such might be the case - or not. The middle ground - and safer path - is to override the behaviour only for the base class and those subclasses that do not depend on the default behavior as was done by JEP 425... ------------- PR: https://git.openjdk.org/jdk/pull/6935