Skip to content

Generated avaje-jsonb code does not work when using generic return types #542

Closed
@ferrazoli

Description

@ferrazoli

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));

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions