How to retrieve the managed Router instance in Quarkus

47 Views Asked by At

I was following this guide to try and work with Vertx and the Router directly but i can't manage to retrieve the managed instance of Router.

I'm simply doing this:


@QuarkusMainpublic 
class Main {

  public static void main(String... args) {
    Quarkus.run(MyApp.class, args);
  }

  static class MyApp implements QuarkusApplication {

    @Override    
    public int run(String... args) {
      Router router = CDI.current().select(Router.class).get();
      Quarkus.waitForExit();
      return 0;
    }
  }
}

And the application fails on CDI.current().select(Router.class).get(); with: jakarta.enterprise.inject.UnsatisfiedResolutionException: No bean found for required type [interface io.vertx.ext.web.Router] and qualifiers [[]]

My dependencies are as follows:

dependencies {
    implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
    implementation("io.quarkus:quarkus-resteasy-reactive-jackson")
    implementation("io.quarkus:quarkus-resteasy-reactive")
    implementation("io.quarkus:quarkus-arc")
    testImplementation("io.quarkus:quarkus-junit5")
    testImplementation("io.rest-assured:rest-assured")
}

Is the context not fully initialized by this time? Any ideas?

UPDATE

As suggested in the comment I tried adding the exact dependencies from the guide:

dependencies {
  implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
  implementation("io.quarkus:quarkus-arc")
  implementation("io.vertx:vertx-web")
  implementation("io.quarkus:quarkus-vertx-http")
  testImplementation("io.quarkus:quarkus-junit5")
  testImplementation("io.rest-assured:rest-assured")
}

But still no luck. quarkus-vertx-http was on the classpath before as well as a transitive dependency and that's why I didn't add it specifically. But yeah so that did not solve it unfortunately.

2

There are 2 best solutions below

0
Oliver Marienfeld On BEST ANSWER

The guide you are referring to was written for Quarkus 1.11. Probably, you are using a more recent version which removes "unused" beans more aggressively, see here.

You have two options how to get the Router:

  1. Obtain it via @Inject (this is standard for Quarkus)
class MyApp implements QuarkusApplication {

  @Inject
  Router router;

  @Override    
  public int run(String... args) {
    router.get("/bye").handler(ctx -> {
      ctx.end("Goodbye.");
      Quarkus.asyncExit();
    });
    router.get().handler(ctx -> ctx.end("Hello from Quarkus!"));
    Quarkus.waitForExit();
    return 0;
  }
}
  1. Instruct Quarkus ARC not to remove the Router bean by setting this in your application.properties:
quarkus.arc.unremovable-types=io.vertx.ext.web.Router
0
geoand On

The reason you are seeing the behavior you describe is that you are trying to obtain the Router bean programmatically, i.e. using

CDI.current().select(...)

When this is done, Quarkus does not know at build time that Router is needed and therefore considers it an unused bean.

The solution is to either use

quarkus.arc.unremovable-types=io.vertx.ext.web.Router

as @oliver-marienfeld mentions, or to restructure your code to inject the Router using field or constructor injection.