Skip to content

Application model

View Markdown

Every piece of the Dagger wiring in a Vertique application has an owner. This page explains who owns each piece: what the launcher does before your code runs, what your own Dagger component and module compose, what code generation produces for you, how starters compose framework capability, and how lifecycle phases order verticle deployment. It uses the REST application generated in Quickstart as its running example.

Your AppModule, the starter’s RestApplicationModule, and the generated GeneratedJaxRsResourcesModule compose into your AppComponent, which extends the framework’s passive VertiqueApplicationComponent contract and is driven by the framework’s lifecycle runner

The pieces fit together as follows. Each one is explained in full further down this page, in its own module reference, or on its own corpus page:

  • Application component. Every application supplies its own Dagger @Component. On the supported path it is annotated @VertiqueApp, which generates the component factory a manual registration would otherwise supply. See What your application owns.
  • Verticles and deployments. Your application contributes VerticleDeployment entries into a named lifecycle phase, and the framework deploys each phase’s verticles in order. See How lifecycle phases order deployments.
  • Launcher vs. runner. vertique-launcher’s VertiqueApplication is the host-specific entrypoint that builds the real Vertx instance and discovers your component. It hands off to the host-neutral lifecycle runner, which drives the phases. See What the launcher owns and the vertique-application module reference.
  • Starters vs. direct modules. A starter composes a fixed set of framework modules behind one class name, and which modules it includes is a release-line compatibility surface. Capability with no starter is named directly as a framework module in your own component. See What starters own and the supported path.
  • Code generation. Annotation processors emit Dagger modules, such as GeneratedJaxRsResourcesModule, from your own annotated classes at compile time, so you do not hand-write their bindings. See What code generation produces.
  • Configuration. Your Dagger modules read typed configuration parsed from the merged JSON/properties/environment/system-property tree. See Configuration.
  • Durable work. Workflows, jobs, and inbox/outbox messaging plug into the same component and lifecycle phases as everything else. They are composed as direct modules rather than through a starter. See Workflows.
  • The management plane. Health and readiness live on a management surface separate from the application edge (port 9090 in generated applications). Liveness answers whether the process can run, and readiness answers whether it should receive traffic. See Deployment.

vertique-launcher supplies VertiqueApplication, the framework-owned entrypoint every generated application runs as its Main-Class. Before your Dagger graph exists, VertiqueApplication resolves the application’s configuration on a temporary Vert.x instance, builds the real Vertx instance, discovers your application’s component factory via ServiceLoader, and drives the deployed application through to shutdown. A bootstrap-configuration failure exits with code 11; a verticle deploy failure exits with code 15.

Because the REST archetype places @VertiqueApp on AppComponent (below), the generated project needs no hand-written main class or manifest entry. The annotation is enough to register the factory the launcher discovers. The generated project depends on both vertique-starter-rest and vertique-launcher, and mvn -ntp exec:java (the command the quickstart uses to start the application) runs VertiqueApplication as the Main-Class. Your application code never calls the launcher directly.

Every Vertique application supplies its own Dagger @Component and at least one application-owned module contributing deployment entries. This is AppComponent from the generated REST application:

@VertiqueApp
@Singleton
@Component(
modules = {
RestApplicationModule.class,
AppModule.class,
GeneratedJaxRsResourcesModule.class
})
interface AppComponent extends VertiqueApplicationComponent {}

AppComponent extends VertiqueApplicationComponent, the passive DI boundary the framework’s lifecycle runner drives. It exposes only the application’s startup steps, its shutdown steps, and its verticle deployment manager. The component does not start itself.

AppModule, in the same generated project, is the application-owned module that makes this component serve traffic (package and import lines omitted for focus):

@Module
class AppModule {
@Provides
@IntoSet
static VerticleDeployment managementVerticle(Provider<ManagementVerticle> provider) {
return VerticleDeployment.of("management", provider::get, LifecyclePhase.INFRA);
}
@Provides
@IntoSet
static VerticleDeployment httpVerticle(Provider<HttpVerticle> provider) {
return VerticleDeployment.of("http", provider::get, LifecyclePhase.EDGE);
}
}

It contributes two @Provides @IntoSet bindings: a management verticle deployed at the INFRA lifecycle phase, and an http verticle deployed at the EDGE lifecycle phase. RestApplicationModule and GeneratedJaxRsResourcesModule contribute no deployment entries of their own. Without AppModule, this component builds a complete graph but serves neither surface.

GeneratedJaxRsResourcesModule, named directly in AppComponent above, is annotation-processor output. It is generated from the project’s JAX-RS resource classes (HelloResource in the quickstart) and carries their Dagger bindings. Generated modules like this one are never reachable from a framework starter aggregate. They must be listed in your @Component explicitly, as AppComponent does here.

RestApplicationModule, from vertique-starter-rest, is the framework aggregate AppComponent names for a REST-serving application. Starter aggregate membership (which modules a named starter includes, and only those) is a release-line compatibility surface. Consumers may rely on it, and a change to it is treated as compatibility-affecting. Vertique publishes four such aggregates:

Starter Aggregate When to use it
vertique-starter-core CoreApplicationModule Lifecycle foundation only: no HTTP, no event bus, no persistence
vertique-starter-rest RestApplicationModule Serves an HTTP API through JAX-RS resources; already includes CoreApplicationModule
vertique-starter-services ServicesApplicationModule Typed service-contract execution; already includes CoreApplicationModule
vertique-starter-postgresql PostgresqlPersistenceModule PostgreSQL pooling and Flyway migration wiring; composed alongside an application starter, never in place of one

An application names only the starters it needs, and never repeats a module a starter already reaches transitively. vertique-starter-postgresql is an independent capability and is not an application foundation. It supplies no Vertx binding, no config parser, and no lifecycle runner on its own, so it is always paired with vertique-starter-core, -rest, or -services.

The framework’s lifecycle runner drives eight ordered phases: CONFIGURE, VALIDATE, MIGRATE, BOOTSTRAP, INFRA, SERVICES, EDGE, and AFTER_START. For each phase, in that order, it runs the phase’s contributed startup steps. For the four phases that carry deployments (BOOTSTRAP, INFRA, SERVICES, EDGE), it then deploys that phase’s verticles.

The launcher resolves bootstrap configuration, builds the Vertx instance, discovers your component factory, and hands the component to the lifecycle runner, which drives the eight ordered phases; the generated REST application’s schema migrations, management verticle, and http verticle land in MIGRATE, INFRA, and EDGE

In the generated REST application, AppModule’s two deployment entries land in two different phases: the management verticle deploys at INFRA, before the http verticle deploys at EDGE. The management (health) surface is therefore up before the HTTP surface starts serving traffic. Adding the PostgreSQL starter to the same component inserts a MIGRATE-phase startup step that runs schema migrations before any of these verticle phases deploy.