Skip to content

Missing @since JavaDoc tags - no version tracking for API additions #142

@sfloess

Description

@sfloess

Description

No JavaDoc comments contain @since tags to indicate when methods, classes, or features were added. This makes it impossible for users to know which version introduced specific functionality, complicating API version management.

Current State

❌ No @SInCE Tags Anywhere

grep -rn "@since" src/main/java --include="*.java"
# Returns: 0 results

❌ No @Version Tags

grep -rn "@version" src/main/java --include="*.java"
# Returns: 0 results

✅ Version in pom.xml

<version>1.31</version>

Why @SInCE Tags Matter

1. API Version Tracking

Without @SInCE:

/**
 * Validates that a string is not null, empty, or whitespace-only.
 */
public static String requireNonBlank(final String string, final String message) {

Users can't tell:

  • When was this method added?
  • Is it safe to use in my project (depends on jcommons 1.20)?
  • Was this in the original release?

With @SInCE:

/**
 * Validates that a string is not null, empty, or whitespace-only.
 * 
 * @param string the string to validate
 * @param message the error message
 * @return the validated string
 * @throws IllegalArgumentException if the string is blank
 * @since 1.28
 */
public static String requireNonBlank(final String string, final String message) {

Now users know:

  • Added in version 1.28
  • Safe if depending on 1.28+
  • Relatively recent addition

2. Deprecation Context

Current deprecation:

@Deprecated(since = "1.22", forRemoval = true)
public static String toString(final Serializable serializable) {

But there's no @since showing when it was added:

  • Was it added in 1.0 and deprecated in 1.22?
  • Or added in 1.20 and deprecated in 1.22?
  • How long was it supported?

Better:

/**
 * @since 1.0
 * @deprecated since 1.22, scheduled for removal in 2.0
 */
@Deprecated(since = "1.22", forRemoval = true)

3. Migration Planning

Users upgrading from old versions need to know:

  • "We're on jcommons 1.15, upgrading to 1.31"
  • "What new APIs are available?"
  • "Which methods didn't exist in 1.15?"

Without @since, they must:

  • Read CHANGELOG (if accurate)
  • Check Git history
  • Trial and error

4. Documentation Quality

Major libraries use @since:

  • Spring Framework: Every public API has @since
  • Apache Commons: Comprehensive @since tags
  • Java Standard Library: All APIs tagged

Example from Spring:

/**
 * @since 5.0
 */
public interface WebFluxConfigurer {

Example from Java:

/**
 * @since 1.8
 */
default void forEach(Consumer<? super T> action) {

5. IDE Integration

IDEs show @since in code completion:

  • IntelliJ shows "Since: 1.28" in popup
  • Eclipse displays version info
  • Helps developers avoid newer APIs

Impact

  • Severity: Low-Medium
  • Type: Documentation / API Management
  • No way to track API additions
  • Harder to plan version upgrades
  • Unprofessional documentation
  • Missing industry best practice

Recommended Fix

1. Add @SInCE to All Public APIs

Classes:

/**
 * Utility class for SOAP operations.
 * 
 * @author sfloess
 * @since 1.0
 */
public final class SoapUtil {

Methods (added in initial version):

/**
 * Sets the endpoint URL.
 * 
 * @param port the port
 * @param url the URL
 * @return the configured port
 * @since 1.0
 */
public static <T> T setUrl(final T port, final String url) {

Methods (added later):

/**
 * Validates non-blank string.
 * 
 * @param string the string to validate
 * @return the validated string
 * @since 1.28
 */
public static String requireNonBlank(final String string) {

New features:

/**
 * Record for SOAP service configuration.
 * 
 * @param service the SOAP service
 * @param portType the port type
 * @since 1.30
 */
public record SoapRecord<T>(Service service, Class<T> portType) {

2. Determine When Each API Was Added

For existing APIs:

Option A - Conservative (mark all as 1.0):

/**
 * @since 1.0
 */

Option B - Research from Git:

# Find when file was added
git log --follow --format=%H --reverse -- src/main/java/org/flossware/jcommons/util/SoapUtil.java | head -1

# Find commit details
git show <commit-hash>

# Check tags at that time
git describe --tags <commit-hash>

Option C - Use CHANGELOG:

  • Review CHANGELOG.md for "Added" sections
  • Correlate features to versions

For new APIs going forward:

  • Add @since with current version
  • Document in CHANGELOG

3. Update CONTRIBUTING.md

Add to documentation standards:

## JavaDoc Requirements

All public APIs must include:

### Classes
```java
/**
 * Brief description.
 * 
 * <p>Detailed description if needed.
 * 
 * @author Your Name
 * @since X.Y (version when class was added)
 */
public class MyClass {

Methods

/**
 * Brief description.
 * 
 * @param name description
 * @return description
 * @throws Exception description
 * @since X.Y (version when method was added)
 */
public void myMethod(String name) {

Deprecations

/**
 * @since X.Y (when it was added)
 * @deprecated since X.Z, use {@link #newMethod()} instead
 */
@Deprecated(since = "X.Z", forRemoval = true)
public void oldMethod() {

### 4. Add to Checkstyle

Enforce `@since` tags:
```xml
<module name="JavadocMethod">
    <property name="validateThrows" value="true"/>
    <property name="scope" value="public"/>
    <property name="allowMissingParamTags" value="false"/>
    <property name="allowMissingReturnTag" value="false"/>
    <!-- Require @since for public methods -->
</module>

<module name="JavadocType">
    <property name="scope" value="public"/>
    <!-- Can configure to require @since -->
</module>

Or use custom Checkstyle check:

<module name="RegexpSinglelineJava">
    <property name="format" value="^\s*public\s+(class|interface|enum|record)"/>
    <property name="message" value="Public types should have @since tag in JavaDoc"/>
</module>

5. Update maven-javadoc-plugin

Configure to validate @since:

<plugin>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>3.12.0</version>
    <configuration>
        <tags>
            <tag>
                <name>since</name>
                <placement>a</placement>
                <head>Since:</head>
            </tag>
        </tags>
        <show>public</show>
        <failOnWarnings>true</failOnWarnings>
    </configuration>
</plugin>

Migration Strategy

Phase 1: Existing Code (v1.32)

  1. Mark all existing public APIs with @since 1.0

    • Conservative approach
    • Indicates "been there a while"
    • Better than nothing
  2. For features clearly added recently:

    • Check Git history
    • Update with correct version
    • Examples: SoapRecord (added recently)

Phase 2: New Code (v1.32+)

  1. Require @since for all new public APIs
  2. Use current version in development
  3. Update during release if needed

Phase 3: Enforcement (v2.0)

  1. Enable Checkstyle validation
  2. Fail build on missing @since
  3. Make it impossible to forget

Example Updates

SoapUtil (exists since project start)

/**
 * Utility class for Apache CXF SOAP service operations.
 * Provides methods for configuring SOAP endpoints, headers, and QName computation.
 *
 * @author sfloess
 * @since 1.0
 */
public final class SoapUtil {

    /**
     * Gets a new SOAP factory instance.
     * 
     * @return a new SOAPFactory instance
     * @throws SoapException if factory cannot be instantiated
     * @since 1.0
     */
    public static SOAPFactory getSoapFactory() {

SoapRecord (added recently)

/**
 * Record type to hold a SOAP service and the port class type.
 *
 * @param <T> the port type
 * @param service the SOAP service instance
 * @param portType the port class type
 * @author sfloess
 * @since 1.30
 */
public record SoapRecord<T>(Service service, Class<T> portType) {

StringUtil.requireNonBlank (check Git to confirm)

/**
 * Validates that a string is not null, empty, or whitespace-only.
 *
 * @param string the string to validate
 * @param message the error message to use if validation fails
 * @return the validated string
 * @throws IllegalArgumentException if the string is blank
 * @since 1.28
 */
public static String requireNonBlank(final String string, final String message) {

Benefits

  1. Version clarity - Users know when APIs were added
  2. Upgrade planning - Can see new features by version
  3. Professional docs - Industry standard practice
  4. IDE integration - Better code completion info
  5. Deprecation context - Know how long API existed

Automated Script

To add @since 1.0 to all existing APIs:

#!/bin/bash
# Add @since to all public classes without it

for file in $(find src/main/java -name "*.java"); do
    # Check if public class/interface/enum/record
    if grep -q "^public.*class\|^public.*interface\|^public.*enum\|^public.*record" "$file"; then
        # Check if @since already present
        if ! grep -q "@since" "$file"; then
            echo "Adding @since to $file"
            # Add @since before class declaration
            # (This is simplified - real script needs better sed)
        fi
    fi
done

Note: Manual review recommended over automated changes.

Related Issues

Would complement:

This issue adds: When was it added?

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions