apache / apache/rocketmq-clients

[Enhancement] Add JSpecify NullMarked annotations to org.apache.rocketmq.client.apis

Open
#1,350 3 comments 0 reactions 0 assignees View on GitHub
type/enhancement
Dominant language
Java
Stars
505
Forks
313
Avg merge
11h 28m
Merged PRs (30d)
6

Description

### Before Creating the Enhancement Request

- [x] I have confirmed that this should be classified as an enhancement rather than a bug/feature.

### Programming Language of the Client

Java

### Summary

All 32 public types in the `client-apis` module (the gRPC client) lack nullability annotations, causing Kotlin consumers to receive unsafe platform types (`String!`, `Map!`, etc.) with no compile-time nullability guarantees.

### Motivation

Without nullability metadata, Kotlin code using the client-apis has no compile-time guarantees:

```kotlin
// Before: all these are `String!` — Kotlin can't warn you
val topic: String? = view.topic // compiles silently
```

This applies to all four public API packages:

| Package | Types |
|---|---|
| `org.apache.rocketmq.client.apis` | 7 |
| `…client.apis.consumer` | 14 |
| `…client.apis.message` | 4 |
| `…client.apis.producer` | 7 |

Additionally, `SendReceipt.getRecallHandle()` returns a bare `String` while being conditional (upstream's own comment says *"only delay message is supported for now"*). It is the only getter in the gRPC API that breaks the `Optional` convention and lacks documentation of its empty-string sentinel value.

### Describe the Solution You'd Like

1. **`@NullMarked` on four packages** — four `package-info.java` files added (JSpecify package scope is not hierarchical). This marks ~99 return values and parameters as non-null by default across all 32 public types.

2. **JSpecify 1.0.0 as a `provided` dependency** — added to the BOM and `client-apis` module. Annotations are `CLASS` retention, so they are encoded in compiled class files and downstream consumers do not need to add any dependency.

3. **Javadoc fix for `SendReceipt.getRecallHandle()`** — replaced an implementation-level line comment with proper Javadoc documenting that this method returns an empty string (not null) when recall is unsupported. Callers should test with `String.isEmpty()` rather than for nullness.

### Describe Alternatives You've Considered

-

### Additional Context

-

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by locating the client-apis module, its BOM, and the four package-info.java files needed for package-scoped annotations. Review the public types and SendReceipt.getRecallHandle(), then verify that JSpecify is provided, all four packages are covered, and the method Javadoc documents the empty-string behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, kotlin
Domain
api
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.