Closed
Description
I think there's a bug with avaje-jsonb paired with avaje-http when using generic return types.
Here's a simple example to demonstrate:
@Path("/data")
@Controller
public class ExampleController {
@Get
Data<String> getData() {
return null;
}
}
This gets turned into:
@Generated("avaje-javalin-generator")
@Component
public class ExampleController$Route extends AvajeJavalinPlugin {
private final ExampleController controller;
private final JsonType<Data<String>> dataStringJsonType;
public ExampleController$Route(ExampleController controller, Jsonb jsonb) {
this.controller = controller;
this.dataStringJsonType = jsonb.type(Types.newParameterizedType(Data.class, .class));
}
@Override
public void onStart(JavalinConfig cfg) {
cfg.router.mount(this::routes);
}
private void routes(JavalinDefaultRouting app) {
app.get("/data", ctx -> {
ctx.status(200);
var result = controller.getData();
dataStringJsonType.toJson(result, ctx.contentType("application/json").res().getOutputStream());
});
}
}
The problem is in this line specifically:
jsonb.type(Types.newParameterizedType(Data.class, .class));
It seems like it's missing the generic type when creating the jsonb type. Interestingly, the field definition looks correct.
The problem looks worse when using wildcards:
@Path("/data")
@Controller
public class ExampleController {
@Get
Data<?> getData() {
return null;
}
}
Gets turned into:
@Generated("avaje-javalin-generator")
@Component
public class ExampleController$Route extends AvajeJavalinPlugin {
private final ExampleController controller;
private final JsonType<Data<?>> data?JsonType;
public ExampleController$Route(ExampleController controller, Jsonb jsonb) {
this.controller = controller;
this.data?JsonType = jsonb.type(Types.newParameterizedType(Data.class, .class));
}
@Override
public void onStart(JavalinConfig cfg) {
cfg.router.mount(this::routes);
}
private void routes(JavalinDefaultRouting app) {
app.get("/data", ctx -> {
ctx.status(200);
var result = controller.getData();
data?JsonType.toJson(result, ctx.contentType("application/json").res().getOutputStream());
});
}
}
Here, both the field definition and the initialization are wrong:
private final JsonType<Data<?>> data?JsonType;
this.data?JsonType = jsonb.type(Types.newParameterizedType(Data.class, .class));