JDK-8285099 : (ref) Reference object should not support cloning
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 8u42
  • Submitted: 2022-04-19
  • Updated: 2022-04-26
  • Resolved: 2022-04-21
Related Reports
CSR :  
Relates :  
Relates :  
Description
Summary
-------

Update `Reference::clone` to always throw `CloneNotSupportedException`.

Problem
-------

The semantics of cloning a reference object (any instance of `java.lang.ref.Reference`) are not clearly defined.
In addition, it is questionable whether cloning should be supported due
to its tight interaction with garbage collector.

The reachability state of a reference object may change during
GC reference processing.  The reference object may have been cleared
when it reaches its reachability state.  On the other hand, it may
be enqueued or pending for enqueuing.   A newly cloned reference
object could have a referent that is unreachable if the reference
object being cloned is not yet cleared.  A newly cloned reference
object from an enqueued reference object will never be enqueued.

A reference object cannot be meaningfully cloned.

Solution
--------

Update `Reference::clone` to always throw `CloneNotSupportedException`.
To clone a reference object, user code should create a new reference object with a constructor.

Specification
-------------

```
 +    /**
 +     * Throws {@link CloneNotSupportedException}. A {@code Reference} cannot be
 +     * meaningfully cloned. Construct a new {@code Reference} instead.
 +     *
 +     * @apiNote This method is defined in Java SE 8 Maintenance Release 4.
 +     *
 +     * @return  never returns normally
 +     * @throws  CloneNotSupportedException always
 +     *
 +     * @since 8
 +     */
 +    @Override
 +    protected Object clone() throws CloneNotSupportedException {
 +        throw new CloneNotSupportedException();
 +    }
```
Comments
Moving to Approved.
21-04-2022

Follow-up discussion at Oracle agrees that `@since 8` and an accompanying `@apiNote` is a good compromise for a difficult situation. The `8` matches the Specification number, not the JDK version number. For consistency, an `@apiNote` should be added to the MR 3 changes as well (see JDK-8285400).
21-04-2022

In fact, a few new APIs added in MR 3 have @since 8. There is no occurrence of ā€œ8uā€ in Java SE API. Options considered are: 1. `@since 8` : do the same as what we did in MR 3. 2. `@since 8u42` : 8u42 indicates that such API is not present in JDK 8 update release < 8u42. However, it does not indicate which 8 update release (8u352) begins to include such API. 8u42 is the RI for MR 4. It should not be hard to find which 8u update release implements Java SE 8 with MR4 but still cause confusion (e.g. 8u331 did not include this change) None of these options is ideal. This API is not present in all existing 8u releases and `@since` does not correctly reflect which 8u release this API is present. I propose to keep `@since 8` (same as what we did in MR 3) and add `@apiNote` to state which MR this method is defined.
21-04-2022

If it's not restricted to use "8" (the major version of the Java SE release), I propose "@since 8u42" is better which indicates that this API is not present until 8u42.
20-04-2022

Moving to Provisional, not Approved. I suspect value other than "since 8" would work better here.
20-04-2022