RFR 8080225 FileInput/OutputStream/FileChannel cleanup should be improved

Peter Levart peter.levart at gmail.com
Mon Dec 4 13:47:35 UTC 2017

This is a nice exercise in compatible migration from finalize() to 
Cleaner. The compatibility would be even better with a little tweak to 
the VM. Currently VM ignores empty finalize() method(s) and does not 
register the instance for finalization if it has empty finalize() (just 
return bytecode). There could be a special method-level runtime 
annotation, say @IgnoreFinalize that would be used to annotate no-empty 
finalize() methods and would have the same effect as empty method on the 
VM behavior. XXXStream could then just annotate the finalize() and leave 
it as is so that potential overriders of finalize() could call super.

Current approach (with AltFinalizer) is an approximation since it can 
only call finalize() and close() in succession. If overridden finalize() 
callse super.finalize() in the middle of the method, it may expect the 
stream to be already closed for the rest of the method:

protected finalize() {
     ... pre-close logic
     ... post-close logic (may expect stream to be already closed)

...bust since super.close() is empty, the stream is not closed yet and 
will be closed by AltFinalizer after this.finalize() returns.

I don't know what impact does such order have on the compatibility. 
Probably not big.

Regards, Peter

On 12/04/2017 02:25 PM, Peter Levart wrote:
> Hi Rogger,
> On 12/04/2017 02:17 PM, Peter Levart wrote:
>> Hi Rogger,
>> Interesting approach. Conditional finalization. You use finalization 
>> to support cases where user overrides finalize() and/or close() and 
>> Cleaner when he doesn't.
>> I wonder if it is the right thing to use AltFinalizer when user 
>> overrides finalize() method. In that case the method is probably not 
>> empty and calls super.finalize() (if it is empty or doesn't call 
>> super, user probably doesn't want the finalization to close the 
>> stream) and so normal finalization applies. If you register 
>> AltFinalizer for such case, close() will be called twice.
> Ah, scrap that. I forgot that XXXStream.finalize() is now empty, so 
> user overriding it and calling super does not in fact close the 
> stream. You have to register AltFinalizer in that case. But now I 
> wonder if the logic should still be 3-state and do the following:
> - if user overrides finalize() - use AltFinalizer to call both: first 
> finalize() and then close(); else
> - if user overrides close() - use AltFinalizer to call close(); else
> - use Cleaner
> What do you think?
> Regards, Peter

More information about the core-libs-dev mailing list