JDK-8309252 : automatic copying of record constructor @param, similar to method overrides
  • Type: Enhancement
  • Component: tools
  • Sub-Component: javadoc(tool)
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2023-05-28
  • Updated: 2023-06-01
  • Resolved: 2023-06-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 19
19Fixed
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
openjdk 17.0.4 2022-07-19
OpenJDK Runtime Environment Temurin-17.0.4+8 (build 17.0.4+8)
OpenJDK 64-Bit Server VM Temurin-17.0.4+8 (build 17.0.4+8, mixed mode, sharing)

A DESCRIPTION OF THE PROBLEM :
Please improve Javadoc so that if a constructor is provided for a record, for each missing `@param` Javadoc will use the `@param` provided in the record description. This is analogous to how Javadoc already copies method API documentation for a method `@Override` if no documentation is given.

Consider the following Java record, with documentation for each record component:

```java
/**
 * Foo bar record.
 * @param foo That foo thing; cannot be <code>null</code>.
 * @param bar That bar thing; cannot be <code>null</code>.
 */
public record FooBar(String foo, String bar) {
}
```

Java will automatically generate a `FooBar` constructor. In addition Javadoc will automatically copy the record `@param` documentation to the constructor. This works fine.

However it is extremely likely that one will need to validate and normalize arguments, necessitating the addition of a custom constructor:

```java
/**
 * Foo bar record.
 * @param foo That foo thing; cannot be <code>null</code>.
 * @param bar That bar thing; cannot be <code>null</code>.
 */
public record FooBar(String foo, String bar) {

  /** Constructor for argument validation and normalization. */
  public FooBar {
    Objects.requireNonNull(foo);
    Objects.requireNonNull(bar);
  }

}
```

Unfortunately in this case Javadoc no longer copies the `@param` documentation, and worse, `-Xdoclint:all` issues a warning:

```
[WARNING] Javadoc Warnings
[WARNING] …/FooBar.java:xx: warning: no @param for foo
[WARNING] public FooBar {
[WARNING] ^
[WARNING] …/FooBar.java:xx: warning: no @param for bar
[WARNING] public FooBar {
[WARNING] ^
[WARNING] 2 warnings
```

The problem is not with linting or warnings; the problem is that Javadoc did not copy over the `@param` documentation as it did with the generated constructor. This forces the developer to copy and paste needlessly:

```java
/**
 * Foo bar record.
 * @param foo That foo thing; cannot be <code>null</code>.
 * @param bar That bar thing; cannot be <code>null</code>.
 */
public record FooBar(String foo, String bar) {

  /**
   * Constructor for argument validation and normalization.
   * @param foo That foo thing; cannot be <code>null</code>.
   * @param bar That bar thing; cannot be <code>null</code>.
   */
  public FooBar {
    Objects.requireNonNull(foo);
    Objects.requireNonNull(bar);
  }

}
```

In other words, records are now forcing boilerplate upon the developer, when their purpose is to reduce boilerplate.

An analogous situation which Javadoc (now) handles correctly is when overriding methods. A developer may leave off documentation for a method annotated with `@Override`, and Javadoc will copy over the documentation from the overridden class or interface. In this case there is no need for an `@Override` annotation, as the semantics are implicit by the context.

Javadoc provides an `{@inheritDoc}` mechanism for when the developer wants to duplicate the documentation for an overridden method and then add to it. Perhaps Javadoc might provide a `{@defaultDoc}` or `{@recordDoc}` or some similar mechanism to add to the record-level documentation.

Still by default, if no documentation at all is provided for a custom constructor, Javadoc should copy over the record-level `@param` documentation as it does already if no custom constructor is provided, and emit no doclint warning.



Comments
This is no more reproducible in JDK 19, 20 and 21
01-06-2023

I think this was addressed by JDK-8275784 in JDK 19.
29-05-2023