Skip to content

Fix for @Default ignored for "contract-first" style controller - #793

Merged
rbygrave merged 1 commit into
masterfrom
fix/contract-first-defaultAnnotation
Jul 30, 2026
Merged

Fix for @Default ignored for "contract-first" style controller#793
rbygrave merged 1 commit into
masterfrom
fix/contract-first-defaultAnnotation

Conversation

@rbygrave

@rbygrave rbygrave commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Given an interface with a @Default on a @QueryParam like:

@QueryParam("useMaster") @Default("false") boolean useMaster

The @Default("false") was not being read and applied on the query parameter. This resulted in a null being used and a InvalidPathArgumentException.

io.avaje.http.api.InvalidPathArgumentException: path element is null
 at io.avaje.http.api.PathTypeConversion.checkNull(PathTypeConversion.java:52)
 at io.avaje.http.api.PathTypeConversion.asBoolean(PathTypeConversion.java:178)
 at io.avaje.http.api.PathTypeConversion.asBool(PathTypeConversion.java:186)
 ...

The fix has 2 parts:

A) Improve ProcessingContext.superMethods() which only matched on name and instead match also on parameter types etc
B) Fix MethodReader to use the annotated element [from the super method / interface] as the controller method itself does not have those annotations like @Default.


In the generated code, with the bug we see the null value like:

var useMaster = asBool(queryParams.contains("useMaster") ? queryParams.get("useMaster") : null);

... when we expect the default value of "false" like:

var useMaster = asBool(queryParams.contains("useMaster") ? queryParams.get("useMaster") : "false");

Workaround

Copy the annotations from the interface (like @QueryParam("useMaster") @Default("false")) to the controller method. This duplicates the annotations so not ideal but does mean that the generated code includes the default values as expected.

Given an interface with a @default on a @QueryParam like:
```java
@QueryParam("useMaster") @default("false") boolean useMaster
```
The `@Default("false")` was not being read and applied on the query parameter. This resulted in a null being used and a InvalidPathArgumentException.

```
io.avaje.http.api.InvalidPathArgumentException: path element is null
 at io.avaje.http.api.PathTypeConversion.checkNull(PathTypeConversion.java:52)
 at io.avaje.http.api.PathTypeConversion.asBoolean(PathTypeConversion.java:178)
 at io.avaje.http.api.PathTypeConversion.asBool(PathTypeConversion.java:186)
 ...
```

The fix has 2 parts:
A) Improve ProcessingContext.superMethods() which only matched on name and instead match also on parameter types etc
B) Fix MethodReader to use the annotated element [from the super method / interface] as the controller method itself does not have those annotations like @default.
@rbygrave rbygrave self-assigned this Jul 30, 2026
@rbygrave
rbygrave requested a review from SentryMan July 30, 2026 01:08
@rbygrave
rbygrave merged commit 8ccd8b6 into master Jul 30, 2026
7 checks passed
@rbygrave
rbygrave deleted the fix/contract-first-defaultAnnotation branch July 30, 2026 02:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants