JDK-8286064 : Remove finalizer implementation in SSLSocketImpl
  • Type: CSR
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Priority: P3
  • Status: Provisional
  • Resolution: Unresolved
  • Fix Versions: 19
  • Submitted: 2022-05-03
  • Updated: 2022-05-04
Related Reports
CSR :  
Description
Summary
-------
Remove finalizer implementation in `SSLSocket`.

Problem
-------
`java.lang.Object.finalize` has been deprecated for removal as part of [JEP 421](https://openjdk.java.net/jeps/421).  Finalizers should be removed or converted to use `java.lang.ref.Cleaner`.  

Solution
--------
Remove the `SSLSocket` finalizer, which has been implemented in `sun.security.ssl.BaseSSLSocketImpl.finalize()` for many releases.

`BaseSSLSocketImpl` is an extension of `javax.net.ssl.SSLSocket`, and is the super class of the actual implementation `sun.security.ssl.SSLSocketImpl`.   The `BaseSSLSocketImpl,finalize()` was written to ensure that SSL/TLS connections were shutdown as clearly as possible, in case applications forget to properly close.

The finalizer served two purposes:

 1. release the native resources allocated for the socket connection, and
 2. send a TLS close_notify message so that the connection could be closed gracefully in case the application did not close the `Socket` itself.

The java.net.Socket implementation has been updated to release the native resources by using `java.lang.ref.Cleaner`s.  As `SSLSocket` and `BaseSSLSocketImpl` are sub-classes of `java.net.Socket`, the underlying native resources are handled by the `Socket` `Cleaner`, so it is not necessary to repeat the release in the `SSLSocket` implementation any longer.  With this update, there is no behavioral update for native resources releasing.

The behavioral change of this update is about the sending TLS close_notify message during finalization, which previously might have been sent under certain circumstances.  With this update, the close_notify message will not be sent during finalization.

Note that an `SSLSocket` object could be constructed over an existing connected socket (layered socket).  If and only if the preexisting socket was an instance of `SSLSocket`,  a close_notify would be sent so as to clean up the preexisting socket.

Not closing properly is more properly an error condition that should be avoided.  Applications should close sockets and not rely on garbage collection.  Based on that, we propose to remove the `finalize()` implementation completely.

For the removal, here is a summary of the behavioral changes.

 1. The underlying native resources are handled by the socket `Cleaner`. No behavioral changes on this point.
 2. If the TLS connection is not constructed using an existing connected socket, no behavioral changes.
 3. If the TLS connection is constructed using an existing connected socket, and the preexisting socket is NOT an instance of `SSLSocket`, no behavioral changes.
 4.  If the TLS connection is constructed using an existing connected socket, and the preexisting socket is an instance of `SSLSocket`, with the removing of the `finalize()` method, the TLS close_notify message will not be sent and the preexisting socket will not be cleaned up unless applications close sockets explicitly.

Because of garbage collection behavior, garbage collection based preexisting socket cleanup is not reliable and cannot be relied on for serious applications.  As far as I know, we have not heard any complaints on this point.  It may imply that the behavior changes introduced in #4 may be limited.

Specification
-------------
No specification changes.  A release note will be added.
Comments
Moving to Provisional, not Approved. [~rriggs] or [~bchristi], given your prior experience in similar updates, please review this request. [~xuelei], once it has additional reviewers, please re-Finalize the request.
04-05-2022

@dfuchs All good comments, I updated the CSR and release note accordingly.
03-05-2022

The release note should probably mention that close_notify will no longer be emitted if SSLSocket is not explicitly closed. It would be good to get [~wetmore] review before finalizing the CSR.
03-05-2022

You should probably mention in the Solution that the socket file descriptor will continue to be released by the underlying FileDescriptor cleaner even after this change. The behavioral change is that the close_notify message - which previously might have been sent in some circumstances, will now never be sent unless the application explicitly closes the outer socket.
03-05-2022