Skip to content

APT ignores @Inject fields in superclass when generating Mvc route constructors #3804

@goodcwj

Description

@goodcwj

When a controller extends a base class that contains @Inject fields, but the controller itself does not define any @Inject-annotated fields or constructors, the Jooby APT–generated _ router class does not instantiate the controller through the DI container.

Instead, it falls back to new, which bypasses dependency injection. As a result, injected fields inherited from the superclass are null.

example

public abstract class ApiRouteBase {
  @Inject
  protected AdminParamDecoder paramDecoder;
}

Controller:

@Path("/reports")
public class ReportsApi extends ApiRouteBase {
  @GET
  public Object list(Context ctx) {
    return paramDecoder.decodeAdminRequest(ctx);  // paramDecoder is null
  }
}

Runtime response:

{
  "httpCode": 500,
  "httpMessage": "Server Error",
  "type": "internal",
  "userMessage": "Internal error",
  "internalMessage": "Cannot invoke ... because \"this.paramDecoder\" is null"
}

Observed behavior in generated _ router class:

io.jooby.SneakyThrows.singleton(ReportsApi::new)

instead of

ctx.require(ReportsApi.class)

So the controller does not receive DI for the inherited field.

Workarounds##

Add a constructor with @Inject in the controller:

@Inject
  public ReportsApi() {
  }

After doing this, paramDecoder is correctly injected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions