[ 
https://issues.apache.org/jira/browse/FINERACT-2315?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Peter Thua updated FINERACT-2315:
---------------------------------
    Description: 
{color:#0000ff}# SMS Campaign Reports API Returns 500 Internal Server 
Error{color}

{color:#0000ff}## Summary{color}
{color:#000000}API endpoint for retrieving SMS campaign reports by status 
returns a 500 Internal Server Error due to HK2 dependency injection failure 
with record-based parameter classes.{color}

{color:#0000ff}## Environment{color}
{color:#0000ff}- {color}{color:#000000}{*}{{*}}API 
Endpoint:{{*}}{*}{color}{color:#000000} 
{color}{color:#001188}`/fineract-provider/api/v1/sms/\{id}/messageByStatus`{color}
{color:#0000ff}- 
{color}{color:#000000}{*}{{*}}Framework:{{*}}{*}{color}{color:#000000} Jersey 
with HK2 dependency injection{color}
{color:#0000ff}- {color}{color:#000000}{*}{{*}}Java 
Version:{{*}}{*}{color}{color:#000000} 21{color}

{color:#0000ff}## Steps to Reproduce{color}

{color:#0000ff}### Prerequisites{color}
{color:#0000ff}- {color}{color:#000000}Access to Fineract SMS API{color}
{color:#0000ff}- {color}{color:#000000}Valid SMS campaign ID{color}
{color:#0000ff}- {color}{color:#000000}API authentication credentials{color}

{color:#0000ff}### Reproduction Steps{color}
{color:#0000ff}1. {color}{color:#000000}{*}{{*}}Create or identify an existing 
SMS campaign{{*}}{*}{color}
{color:#0000ff}   - {color}{color:#000000}Ensure the campaign has sent 
messages{color}
{color:#0000ff}   - {color}{color:#000000}Note the campaign ID (e.g., 
{color}{color:#001188}`2`{color}{color:#000000}){color}

{color:#0000ff}2. {color}{color:#000000}{*}{{*}}Make API request to retrieve 
campaign reports{{*}}{*}{color}
{color:#a31515}   ```bash{color}
{color:#000000}   GET 
[https://localhost:8443/fineract-provider/api/v1/sms/\|https://localhost:8443/fineract-provider/api/v1/sms/]{{{}id{}}}/messageByStatus?status=100&locale=en&dateFormat=dd
 MMMM yyyy&fromDate=01 June 2025&toDate=17 June 2025{color}
{color:#000000}   {color}{color:#a31515}```{color}
{color:#000000}   {color}
{color:#000000}   Replace 
{color}{color:#001188}`{{{}id{}}}`{color}{color:#000000} with your actual 
campaign ID.{color}

{color:#0000ff}3. {color}{color:#000000}{*}{{*}}Sample query 
parameters:{{*}}{*}{color}
{color:#0000ff}   - {color}{color:#001188}`status=100`{color}{color:#000000} 
(or any valid status code){color}
{color:#0000ff}   - {color}{color:#001188}`locale=en`{color}
{color:#0000ff}   - {color}{color:#001188}`dateFormat=dd MMMM yyyy`{color}
{color:#0000ff}   - {color}{color:#001188}`fromDate=01 June 
2025`{color}{color:#000000} (adjust date as needed){color}
{color:#0000ff}   - {color}{color:#001188}`toDate=17 June 
2025`{color}{color:#000000} (adjust date as needed){color}

{color:#0000ff}4. {color}{color:#000000}{*}{{*}}Execute the 
request{{*}}{*}{color}
{color:#0000ff}   - {color}{color:#000000}Use any HTTP client (Postman, curl, 
browser, etc.){color}
{color:#0000ff}   - {color}{color:#000000}Include necessary authentication 
headers{color}

{color:#0000ff}### Expected Result{color}
{color:#000000}API should return SMS message data filtered by the specified 
status and date range.{color}

{color:#0000ff}### Actual Result{color}
{color:#000000}API returns a 500 Internal Server Error with the following 
response:{color}

{color:#a31515}```json{color}
{color:#000000}{{color}
{color:#000000}  "timestamp": "2025-06-17T12:06:20.745Z",{color}
{color:#000000}  "status": 500,{color}
{color:#000000}  "error": "Internal Server Error",{color}
{color:#000000}  "path": 
"/fineract-provider/api/v1/sms/2/messageByStatus"{color}
{color:#000000}}
```

{color:#0000ff}## Error Details{color}

{color:#0000ff}### Server Console Error{color}
{color:#a31515}```{color}
{color:#001188}org.glassfish.hk2.api.MultiException: A MultiException has 2 
exceptions. They are:{color}
{color:#001188}1. java.lang.NoSuchMethodException: Could not find a suitable 
constructor in org.apache.fineract.infrastructure.sms.param.SmsRequestParam 
class.{color}
{color:#001188}2. java.lang.IllegalArgumentException: Errors were discovered 
while reifying SystemDescriptor(...){color}
{color:#a31515}```{color}

{color:#0000ff}### Error Analysis{color}
{color:#000000}The error occurs in the following sequence:{color}
{color:#0000ff}1. {color}{color:#000000}Jersey receives the HTTP request with 
query parameters{color}
{color:#0000ff}2. {color}{color:#000000}Jersey attempts to create an instance 
of {color}{color:#001188}`SmsRequestParam`{color}{color:#000000} (annotated 
with {color}{color:#001188}`@BeanParam`{color}{color:#000000}){color}
{color:#0000ff}3. {color}{color:#000000}HK2 dependency injection container 
tries to instantiate the parameter class{color}
{color:#0000ff}4. {color}{color:#000000}HK2 fails to find a suitable 
constructor in the record-based 
{color}{color:#001188}`SmsRequestParam`{color}{color:#000000} class{color}
{color:#0000ff}5. 
{color}{color:#001188}`NoSuchMethodException`{color}{color:#000000} is thrown, 
causing the 500 error{color}

{color:#0000ff}## Root Cause{color}

{color:#0000ff}### Technical Details{color}
{color:#0000ff}- {color}{color:#000000}{*}{{*}}Framework 
Incompatibility:{{*}}{*}{color}{color:#000000} Jersey uses HK2 for dependency 
injection, which requires classes to have default constructors for 
instantiation{color}
{color:#0000ff}- {color}{color:#000000}{*}{{*}}Record 
Limitation:{{*}}{*}{color}{color:#000000} Java records only provide 
constructors that accept all declared parameters; they do not have default 
(no-argument) constructors{color}
{color:#0000ff}- {color}{color:#000000}{*}{{*}}Parameter Binding 
Process:{{*}}{*}{color}{color:#000000} The 
{color}{color:#001188}`@BeanParam`{color}{color:#000000} annotation instructs 
Jersey to:{color}
{color:#0000ff}  1. {color}{color:#000000}Create an instance of the parameter 
class using dependency injection{color}
{color:#0000ff}  2. {color}{color:#000000}Populate the instance fields using 
query parameter values{color}
{color:#0000ff}  3. {color}{color:#000000}Pass the populated instance to the 
endpoint method{color}

{color:#0000ff}### Why Records Don't Work{color}
{color:#000000}Records are immutable data carriers that:{color}
{color:#0000ff}- {color}{color:#000000}Automatically generate constructors 
requiring all parameters{color}
{color:#0000ff}- {color}{color:#000000}Do not provide default 
constructors{color}
{color:#0000ff}- {color}{color:#000000}Cannot be instantiated without providing 
all field values upfront{color}

{color:#000000}This conflicts with HK2's instantiation process, which expects 
to create empty instances first and then populate them through setter methods 
or field injection.{color}

{color:#0000ff}## Solution Implemented{color}

{color:#0000ff}### Code Changes{color}
{color:#000000}Converted 
{color}{color:#001188}`SmsRequestParam`{color}{color:#000000} from a record to 
a regular class with:{color}

{color:#000000}{*}{{*}}Before (Record):{{*}}{*}{color}
{color:#a31515}```java{color}
{color:#0000ff}public{color}{color:#000000} 
{color}{color:#0000ff}record{color}{color:#000000} SmsRequestParam(Long status, 
DateParam fromDate, DateParam toDate, String locale, String rawDateFormat, 
Integer offset,{color}
{color:#000000}        Integer limit, String orderBy, String sortOrder) 
{}{color}
{color:#a31515}```{color}

{color:#000000}{*}{{*}}After (Regular Class):{{*}}{*}{color}
{color:#a31515}```java{color}
{color:#808080}@Data{color}
{color:#808080}@NoArgsConstructor{color}
{color:#0000ff}public{color}{color:#000000} 
{color}{color:#0000ff}class{color}{color:#000000} SmsRequestParam {{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"status"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} Long 
status;{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"fromDate"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} 
DateParam fromDate;{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"toDate"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} 
DateParam toDate;{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"locale"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} String 
locale;{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"dateFormat"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} String 
rawDateFormat;{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"offset"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} Integer 
offset;{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"limit"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} Integer 
limit;{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"orderBy"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} String 
orderBy;{color}

{color:#000000}    
{color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"sortOrder"{color}{color:#000000}){color}
{color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} String 
sortOrder;{color}
{color:#000000}}
```

{color:#0000ff}### How the Fix Works{color}
{color:#0000ff}1. {color}{color:#000000}{*}{{*}}Default 
Constructor:{{*}}{*}{color}{color:#000000} Allows HK2 to create an empty 
instance{color}
{color:#0000ff}2. {color}{color:#000000}{*}{{*}}Setter 
Methods:{{*}}{*}{color}{color:#000000} Enable Jersey to populate fields with 
query parameter values{color}
{color:#0000ff}3. {color}{color:#000000}{*}{{*}}Field 
Annotations:{{*}}{*}{color}{color:#000000} 
{color}{color:#001188}`@QueryParam`{color}{color:#000000} annotations directly 
map HTTP parameters to class fields{color}
{color:#0000ff}4. {color}{color:#000000}{*}{{*}}Dependency 
Injection:{{*}}{*}{color}{color:#000000} HK2 can now successfully instantiate 
and populate the parameter object{color}

{color:#0000ff}## Verification{color}
{color:#000000}After implementing the fix:{color}
{color:#0000ff}1. {color}{color:#000000}The API endpoint successfully processes 
requests{color}
{color:#0000ff}2. {color}{color:#000000}Query parameters are correctly mapped 
to the parameter object{color}
{color:#0000ff}3. {color}{color:#000000}SMS campaign reports are returned as 
expected{color}
{color:#0000ff}4. {color}{color:#000000}No more 500 Internal Server Error 
responses{color}

{color:#0000ff}## Impact{color}
{color:#0000ff}- 
{color}{color:#000000}{*}{{*}}Severity:{{*}}{*}{color}{color:#000000} High - 
API endpoint completely non-functional{color}
{color:#0000ff}- {color}{color:#000000}{*}{{*}}Affected 
Users:{{*}}{*}{color}{color:#000000} All users attempting to retrieve SMS 
campaign reports{color}
{color:#0000ff}- 
{color}{color:#000000}{*}{{*}}Workaround:{{*}}{*}{color}{color:#000000} None 
available before fix implementation{color}

{color:#0000ff}## Related Issues{color}
{color:#0000ff}- {color}{color:#000000}Consider reviewing other record-based 
parameter classes in the codebase{color}
{color:#0000ff}- {color}{color:#000000}Evaluate compatibility of Java records 
with Jersey/HK2 framework combination{color}
{color:#0000ff}- {color}{color:#000000}Document best practices for parameter 
binding in the project{color}

  was:
{noformat}
# SMS Campaign Reports API Returns 500 Internal Server Error
## Summary
API endpoint for retrieving SMS campaign reports by status returns a 500 
Internal Server Error due to HK2 dependency injection failure with record-based 
parameter classes.
## Environment
- {}API Endpoint:{} `/fineract-provider/api/v1/sms/{id}/messageByStatus`
- {}Framework:{} Jersey with HK2 dependency injection
- {}Java Version:{} 21
## Steps to Reproduce
### Prerequisites
- Access to Fineract SMS API
- Valid SMS campaign ID
- API authentication credentials
### Reproduction Steps
1. {}Create or identify an existing SMS campaign{}
   - Ensure the campaign has sent messages
   - Note the campaign ID (e.g., `2`)
2. {}Make API request to retrieve campaign reports{}
   ```bash
   GET 
https://localhost:8443/fineract-provider/api/v1/sms/\id/messageByStatus?status=100&locale=en&dateFormat=dd
 MMMM yyyy&fromDate=01 June 2025&toDate=17 June 2025
   ```
   
   Replace `id` with your actual campaign ID.
3. {}Sample query parameters:{}
   - `status=100` (or any valid status code)
   - `locale=en`
   - `dateFormat=dd MMMM yyyy`
   - `fromDate=01 June 2025` (adjust date as needed)
   - `toDate=17 June 2025` (adjust date as needed)
4. {}Execute the request{}
   - Use any HTTP client (Postman, curl, browser, etc.)
   - Include necessary authentication headers
### Expected Result
API should return SMS message data filtered by the specified status and date 
range.
### Actual Result
API returns a 500 Internal Server Error with the following response:
```json
{
  "timestamp": "2025-06-17T12:06:20.745Z",
  "status": 500,
  "error": "Internal Server Error",
  "path": "/fineract-provider/api/v1/sms/2/messageByStatus"
{color:#000000}}
```
## Error Details
### Server Console Error
```
org.glassfish.hk2.api.MultiException: A MultiException has 2 exceptions. They 
are:
1. java.lang.NoSuchMethodException: Could not find a suitable constructor in 
org.apache.fineract.infrastructure.sms.param.SmsRequestParam class.
2. java.lang.IllegalArgumentException: Errors were discovered while reifying 
SystemDescriptor(...)
```
### Error Analysis
The error occurs in the following sequence:
1. Jersey receives the HTTP request with query parameters
2. Jersey attempts to create an instance of `SmsRequestParam` (annotated with 
`@BeanParam`)
3. HK2 dependency injection container tries to instantiate the parameter class
4. HK2 fails to find a suitable constructor in the record-based 
`SmsRequestParam` class
5. `NoSuchMethodException` is thrown, causing the 500 error
## Root Cause
### Technical Details
- {}Framework Incompatibility:{} Jersey uses HK2 for dependency injection, 
which requires classes to have default constructors for instantiation
- {}Record Limitation:{} Java records only provide constructors that accept all 
declared parameters; they do not have default (no-argument) constructors
- {}Parameter Binding Process:{} The `@BeanParam` annotation instructs Jersey 
to:
  1. Create an instance of the parameter class using dependency injection
  2. Populate the instance fields using query parameter values
  3. Pass the populated instance to the endpoint method
### Why Records Don't Work
Records are immutable data carriers that:
- Automatically generate constructors requiring all parameters
- Do not provide default constructors
- Cannot be instantiated without providing all field values upfront
This conflicts with HK2's instantiation process, which expects to create empty 
instances first and then populate them through setter methods or field 
injection.
## Solution Implemented
### Code Changes
Converted `SmsRequestParam` from a record to a regular class with:
{}Before (Record):{}
```java
public record SmsRequestParam(Long status, DateParam fromDate, DateParam 
toDate, String locale, String rawDateFormat, Integer offset,
        Integer limit, String orderBy, String sortOrder) {}
```
{}After (Regular Class):{}
```java
@Data
@NoArgsConstructor
public class SmsRequestParam {
    @QueryParam("status")
    private Long status;
    @QueryParam("fromDate")
    private DateParam fromDate;
    @QueryParam("toDate")
    private DateParam toDate;
    @QueryParam("locale")
    private String locale;
    @QueryParam("dateFormat")
    private String rawDateFormat;
    @QueryParam("offset")
    private Integer offset;
    @QueryParam("limit")
    private Integer limit;
    @QueryParam("orderBy")
    private String orderBy;
    @QueryParam("sortOrder")
    private String sortOrder;
{color:#000000}}
```
### How the Fix Works
1. {}Default Constructor:{} Allows HK2 to create an empty instance
2. {}Setter Methods:{} Enable Jersey to populate fields with query parameter 
values
3. {}Field Annotations:{} `@QueryParam` annotations directly map HTTP 
parameters to class fields
4. {}Dependency Injection:{} HK2 can now successfully instantiate and populate 
the parameter object
## Verification
After implementing the fix:
1. The API endpoint successfully processes requests
2. Query parameters are correctly mapped to the parameter object
3. SMS campaign reports are returned as expected
4. No more 500 Internal Server Error responses
## Impact
- {}Severity:{} High - API endpoint completely non-functional
- {}Affected Users:{} All users attempting to retrieve SMS campaign reports
- {}Workaround:{} None available before fix implementation
## Related Issues
- Consider reviewing other record-based parameter classes in the codebase
- Evaluate compatibility of Java records with Jersey/HK2 framework combination
- Document best practices for parameter binding in the project{noformat}


> Error Reading SMS Campaing Reports e.g. Pending or Sent SMS
> -----------------------------------------------------------
>
>                 Key: FINERACT-2315
>                 URL: https://issues.apache.org/jira/browse/FINERACT-2315
>             Project: Apache Fineract
>          Issue Type: Bug
>            Reporter: Peter Thua
>            Priority: Major
>         Attachments: image-2025-06-19-09-26-39-710.png
>
>
> {color:#0000ff}# SMS Campaign Reports API Returns 500 Internal Server 
> Error{color}
> {color:#0000ff}## Summary{color}
> {color:#000000}API endpoint for retrieving SMS campaign reports by status 
> returns a 500 Internal Server Error due to HK2 dependency injection failure 
> with record-based parameter classes.{color}
> {color:#0000ff}## Environment{color}
> {color:#0000ff}- {color}{color:#000000}{*}{{*}}API 
> Endpoint:{{*}}{*}{color}{color:#000000} 
> {color}{color:#001188}`/fineract-provider/api/v1/sms/\{id}/messageByStatus`{color}
> {color:#0000ff}- 
> {color}{color:#000000}{*}{{*}}Framework:{{*}}{*}{color}{color:#000000} Jersey 
> with HK2 dependency injection{color}
> {color:#0000ff}- {color}{color:#000000}{*}{{*}}Java 
> Version:{{*}}{*}{color}{color:#000000} 21{color}
> {color:#0000ff}## Steps to Reproduce{color}
> {color:#0000ff}### Prerequisites{color}
> {color:#0000ff}- {color}{color:#000000}Access to Fineract SMS API{color}
> {color:#0000ff}- {color}{color:#000000}Valid SMS campaign ID{color}
> {color:#0000ff}- {color}{color:#000000}API authentication credentials{color}
> {color:#0000ff}### Reproduction Steps{color}
> {color:#0000ff}1. {color}{color:#000000}{*}{{*}}Create or identify an 
> existing SMS campaign{{*}}{*}{color}
> {color:#0000ff}   - {color}{color:#000000}Ensure the campaign has sent 
> messages{color}
> {color:#0000ff}   - {color}{color:#000000}Note the campaign ID (e.g., 
> {color}{color:#001188}`2`{color}{color:#000000}){color}
> {color:#0000ff}2. {color}{color:#000000}{*}{{*}}Make API request to retrieve 
> campaign reports{{*}}{*}{color}
> {color:#a31515}   ```bash{color}
> {color:#000000}   GET 
> [https://localhost:8443/fineract-provider/api/v1/sms/\|https://localhost:8443/fineract-provider/api/v1/sms/]{{{}id{}}}/messageByStatus?status=100&locale=en&dateFormat=dd
>  MMMM yyyy&fromDate=01 June 2025&toDate=17 June 2025{color}
> {color:#000000}   {color}{color:#a31515}```{color}
> {color:#000000}   {color}
> {color:#000000}   Replace 
> {color}{color:#001188}`{{{}id{}}}`{color}{color:#000000} with your actual 
> campaign ID.{color}
> {color:#0000ff}3. {color}{color:#000000}{*}{{*}}Sample query 
> parameters:{{*}}{*}{color}
> {color:#0000ff}   - {color}{color:#001188}`status=100`{color}{color:#000000} 
> (or any valid status code){color}
> {color:#0000ff}   - {color}{color:#001188}`locale=en`{color}
> {color:#0000ff}   - {color}{color:#001188}`dateFormat=dd MMMM yyyy`{color}
> {color:#0000ff}   - {color}{color:#001188}`fromDate=01 June 
> 2025`{color}{color:#000000} (adjust date as needed){color}
> {color:#0000ff}   - {color}{color:#001188}`toDate=17 June 
> 2025`{color}{color:#000000} (adjust date as needed){color}
> {color:#0000ff}4. {color}{color:#000000}{*}{{*}}Execute the 
> request{{*}}{*}{color}
> {color:#0000ff}   - {color}{color:#000000}Use any HTTP client (Postman, curl, 
> browser, etc.){color}
> {color:#0000ff}   - {color}{color:#000000}Include necessary authentication 
> headers{color}
> {color:#0000ff}### Expected Result{color}
> {color:#000000}API should return SMS message data filtered by the specified 
> status and date range.{color}
> {color:#0000ff}### Actual Result{color}
> {color:#000000}API returns a 500 Internal Server Error with the following 
> response:{color}
> {color:#a31515}```json{color}
> {color:#000000}{{color}
> {color:#000000}  "timestamp": "2025-06-17T12:06:20.745Z",{color}
> {color:#000000}  "status": 500,{color}
> {color:#000000}  "error": "Internal Server Error",{color}
> {color:#000000}  "path": 
> "/fineract-provider/api/v1/sms/2/messageByStatus"{color}
> {color:#000000}}
> ```
> {color:#0000ff}## Error Details{color}
> {color:#0000ff}### Server Console Error{color}
> {color:#a31515}```{color}
> {color:#001188}org.glassfish.hk2.api.MultiException: A MultiException has 2 
> exceptions. They are:{color}
> {color:#001188}1. java.lang.NoSuchMethodException: Could not find a suitable 
> constructor in org.apache.fineract.infrastructure.sms.param.SmsRequestParam 
> class.{color}
> {color:#001188}2. java.lang.IllegalArgumentException: Errors were discovered 
> while reifying SystemDescriptor(...){color}
> {color:#a31515}```{color}
> {color:#0000ff}### Error Analysis{color}
> {color:#000000}The error occurs in the following sequence:{color}
> {color:#0000ff}1. {color}{color:#000000}Jersey receives the HTTP request with 
> query parameters{color}
> {color:#0000ff}2. {color}{color:#000000}Jersey attempts to create an instance 
> of {color}{color:#001188}`SmsRequestParam`{color}{color:#000000} (annotated 
> with {color}{color:#001188}`@BeanParam`{color}{color:#000000}){color}
> {color:#0000ff}3. {color}{color:#000000}HK2 dependency injection container 
> tries to instantiate the parameter class{color}
> {color:#0000ff}4. {color}{color:#000000}HK2 fails to find a suitable 
> constructor in the record-based 
> {color}{color:#001188}`SmsRequestParam`{color}{color:#000000} class{color}
> {color:#0000ff}5. 
> {color}{color:#001188}`NoSuchMethodException`{color}{color:#000000} is 
> thrown, causing the 500 error{color}
> {color:#0000ff}## Root Cause{color}
> {color:#0000ff}### Technical Details{color}
> {color:#0000ff}- {color}{color:#000000}{*}{{*}}Framework 
> Incompatibility:{{*}}{*}{color}{color:#000000} Jersey uses HK2 for dependency 
> injection, which requires classes to have default constructors for 
> instantiation{color}
> {color:#0000ff}- {color}{color:#000000}{*}{{*}}Record 
> Limitation:{{*}}{*}{color}{color:#000000} Java records only provide 
> constructors that accept all declared parameters; they do not have default 
> (no-argument) constructors{color}
> {color:#0000ff}- {color}{color:#000000}{*}{{*}}Parameter Binding 
> Process:{{*}}{*}{color}{color:#000000} The 
> {color}{color:#001188}`@BeanParam`{color}{color:#000000} annotation instructs 
> Jersey to:{color}
> {color:#0000ff}  1. {color}{color:#000000}Create an instance of the parameter 
> class using dependency injection{color}
> {color:#0000ff}  2. {color}{color:#000000}Populate the instance fields using 
> query parameter values{color}
> {color:#0000ff}  3. {color}{color:#000000}Pass the populated instance to the 
> endpoint method{color}
> {color:#0000ff}### Why Records Don't Work{color}
> {color:#000000}Records are immutable data carriers that:{color}
> {color:#0000ff}- {color}{color:#000000}Automatically generate constructors 
> requiring all parameters{color}
> {color:#0000ff}- {color}{color:#000000}Do not provide default 
> constructors{color}
> {color:#0000ff}- {color}{color:#000000}Cannot be instantiated without 
> providing all field values upfront{color}
> {color:#000000}This conflicts with HK2's instantiation process, which expects 
> to create empty instances first and then populate them through setter methods 
> or field injection.{color}
> {color:#0000ff}## Solution Implemented{color}
> {color:#0000ff}### Code Changes{color}
> {color:#000000}Converted 
> {color}{color:#001188}`SmsRequestParam`{color}{color:#000000} from a record 
> to a regular class with:{color}
> {color:#000000}{*}{{*}}Before (Record):{{*}}{*}{color}
> {color:#a31515}```java{color}
> {color:#0000ff}public{color}{color:#000000} 
> {color}{color:#0000ff}record{color}{color:#000000} SmsRequestParam(Long 
> status, DateParam fromDate, DateParam toDate, String locale, String 
> rawDateFormat, Integer offset,{color}
> {color:#000000}        Integer limit, String orderBy, String sortOrder) 
> {}{color}
> {color:#a31515}```{color}
> {color:#000000}{*}{{*}}After (Regular Class):{{*}}{*}{color}
> {color:#a31515}```java{color}
> {color:#808080}@Data{color}
> {color:#808080}@NoArgsConstructor{color}
> {color:#0000ff}public{color}{color:#000000} 
> {color}{color:#0000ff}class{color}{color:#000000} SmsRequestParam {{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"status"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} Long 
> status;{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"fromDate"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} 
> DateParam fromDate;{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"toDate"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} 
> DateParam toDate;{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"locale"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} String 
> locale;{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"dateFormat"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} String 
> rawDateFormat;{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"offset"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} 
> Integer offset;{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"limit"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} 
> Integer limit;{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"orderBy"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} String 
> orderBy;{color}
> {color:#000000}    
> {color}{color:#808080}@QueryParam{color}{color:#000000}({color}{color:#a31515}"sortOrder"{color}{color:#000000}){color}
> {color:#000000}    {color}{color:#0000ff}private{color}{color:#000000} String 
> sortOrder;{color}
> {color:#000000}}
> ```
> {color:#0000ff}### How the Fix Works{color}
> {color:#0000ff}1. {color}{color:#000000}{*}{{*}}Default 
> Constructor:{{*}}{*}{color}{color:#000000} Allows HK2 to create an empty 
> instance{color}
> {color:#0000ff}2. {color}{color:#000000}{*}{{*}}Setter 
> Methods:{{*}}{*}{color}{color:#000000} Enable Jersey to populate fields with 
> query parameter values{color}
> {color:#0000ff}3. {color}{color:#000000}{*}{{*}}Field 
> Annotations:{{*}}{*}{color}{color:#000000} 
> {color}{color:#001188}`@QueryParam`{color}{color:#000000} annotations 
> directly map HTTP parameters to class fields{color}
> {color:#0000ff}4. {color}{color:#000000}{*}{{*}}Dependency 
> Injection:{{*}}{*}{color}{color:#000000} HK2 can now successfully instantiate 
> and populate the parameter object{color}
> {color:#0000ff}## Verification{color}
> {color:#000000}After implementing the fix:{color}
> {color:#0000ff}1. {color}{color:#000000}The API endpoint successfully 
> processes requests{color}
> {color:#0000ff}2. {color}{color:#000000}Query parameters are correctly mapped 
> to the parameter object{color}
> {color:#0000ff}3. {color}{color:#000000}SMS campaign reports are returned as 
> expected{color}
> {color:#0000ff}4. {color}{color:#000000}No more 500 Internal Server Error 
> responses{color}
> {color:#0000ff}## Impact{color}
> {color:#0000ff}- 
> {color}{color:#000000}{*}{{*}}Severity:{{*}}{*}{color}{color:#000000} High - 
> API endpoint completely non-functional{color}
> {color:#0000ff}- {color}{color:#000000}{*}{{*}}Affected 
> Users:{{*}}{*}{color}{color:#000000} All users attempting to retrieve SMS 
> campaign reports{color}
> {color:#0000ff}- 
> {color}{color:#000000}{*}{{*}}Workaround:{{*}}{*}{color}{color:#000000} None 
> available before fix implementation{color}
> {color:#0000ff}## Related Issues{color}
> {color:#0000ff}- {color}{color:#000000}Consider reviewing other record-based 
> parameter classes in the codebase{color}
> {color:#0000ff}- {color}{color:#000000}Evaluate compatibility of Java records 
> with Jersey/HK2 framework combination{color}
> {color:#0000ff}- {color}{color:#000000}Document best practices for parameter 
> binding in the project{color}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to