Guice-first integration layer for Vert.x 5. Bootstraps Vert.x from the GuicedEE lifecycle, wires verticles and event-bus endpoints through dependency injection, and supplies codecs and Mutiny-friendly helpers so you can stay inside one DI container while building reactive services.
- Vert.x lifecycle managed by GuicedEE —
Vertxis injected everywhere viaVertXModule - Annotation-driven consumers —
@VertxEventDefinition+@VertxEventOptionswith worker threads, instance counts, local-only, and backpressure hints - Injectable publishers —
@Namedor@VertxEventDefinition, returning Vert.xFutureor MutinyUni - Automatic JSON mapping — codec registration through
CodecRegistryand Jackson - Per-address consumer verticles — each consumer runs in its own dedicated verticle
- Publisher-side throttling — FIFO queuing with configurable rate, no message loss
- Runtime configuration — annotations (
@VertX,@EventBusOptions,@FileSystemOptions,@MetricsOptions) plus SPI hooks (VertxConfigurator,ClusterVertxConfigurator,VerticleStartup) - Authentication & Authorization — annotation-driven auth via
@AuthOptionswithChainAuth,KeyStoreOptions,PubSecKeyOptions, PRNG, and SPI-based provider registration
<dependency>
<groupId>com.guicedee</groupId>
<artifactId>vertx</artifactId>
</dependency>Gradle (Kotlin DSL)
implementation("com.guicedee:guiced-vertx:2.0.0-RC10")Bootstrapping is automatic — call IGuiceContext.instance().inject() and VertXModule is discovered via SPI:
IGuiceContext.registerModuleForScanning.add("my.app");
IGuiceContext.instance();Tune Vert.x at the package or type level:
@VertX(workerPoolSize = 32, haEnabled = true)
@EventBusOptions(clusterPublicHost = "127.0.0.1", preferNativeTransport = true)
class VertxRuntimeConfig {}Method-based consumers are the preferred style — the registry scans your classpath and binds them automatically:
import io.smallrye.mutiny.Uni;
public class GreetingConsumers {
@VertxEventDefinition(value = "greeting.received",
options = @VertxEventOptions(worker = true))
public String handleGreeting(Message<Anything> message) {
return "Hello " + message.body();
}
@VertxEventDefinition("user.created")
public Uni<Void> trackUser(Anything payload) {
return Uni.createFrom().voidItem();
}
}- One verticle per address —
VertxConsumersStartupdeploys anEventConsumerVerticlefor every discovered event address - Scaling —
@VertxEventOptions.instances()> 1 deploys multiple consumer verticles with round-robin - Worker execution —
options.worker()dispatches off the event loop to a named worker pool - Local-only —
options.localOnly()registers a local consumer inside its per-address verticle - Type mapping — non-Vert.x parameter types are mapped automatically via Jackson
Inject a publisher using @Named:
import io.smallrye.mutiny.Uni;
public class GreetingPublisher {
@Inject
@Named("greeting.received")
private VertxEventPublisher<String> publisher;
public Uni<String> greet(String name) {
return publisher.send(name); // request/response
}
public void broadcast(UserCreated event) {
publisher.publish(event); // fire to all consumers
}
}Publisher-side throttling prevents flooding without message loss:
publish()and fire-and-forgetsend()are enqueued (FIFO) and drained at a configurable rate (default 50 ms)request()remains immediate — no timeouts introduced- Per-instance queues — each publisher throttles independently
| Environment variable | Default | Purpose |
|---|---|---|
VERTX_PUBLISH_THROTTLE_MS |
50 |
Global throttle period (0 = disabled) |
VERTX_PUBLISH_THROTTLE_MS_<ADDR> |
— | Per-address override |
VERTX_PUBLISH_QUEUE_WARN |
1000 |
Backlog warning threshold |
VERTX_PUBLISH_QUEUE_WARN_<ADDR> |
— | Per-address warning threshold |
Address normalization: upper-case, replace
.and-with_(e.g.orders.events→ORDERS_EVENTS)
Override event bus addresses and consumer options at runtime via system properties or environment variables:
| Variable | Type | Purpose |
|---|---|---|
VERTX_EVENT_ADDRESS_<ADDR> |
string | Override the resolved address |
VERTX_EVENT_LOCAL_ONLY |
boolean | Force local-only consumers |
VERTX_EVENT_CONSUMER_COUNT |
int | Default consumer count |
VERTX_EVENT_WORKER |
boolean | Default worker mode |
VERTX_EVENT_WORKER_POOL |
string | Worker pool name |
VERTX_EVENT_WORKER_POOL_SIZE |
int | Worker pool size |
VERTX_EVENT_INSTANCES |
int | Verticle instances per address |
VERTX_EVENT_TIMEOUT_MS |
long | Consumer timeout |
VERTX_EVENT_BATCH_WINDOW_MS |
int | Batch window |
VERTX_EVENT_BATCH_MAX |
int | Max batch size |
VERTX_EVENT_MAX_BUFFERED_MESSAGES |
int | Backpressure buffer limit |
VERTX_EVENT_RESUME_AT_MESSAGES |
int | Resume threshold |
Built-in support for Vert.x Common Auth — annotation-driven configuration with Guice injection for all auth types.
Place @AuthOptions on a class or package-info.java:
@AuthOptions(
chainMode = AuthOptions.ChainMode.ANY,
keyStore = @AuthKeyStore(
path = "/path/to/keystore.pkcs12",
type = "pkcs12",
password = "changeit"
),
pubSecKeys = {
@AuthPubSecKey(algorithm = "RS256", path = "/path/to/public.pem")
},
prngAlgorithm = "SHA1PRNG",
leeway = 5
)
package com.example.auth;Register custom authentication providers via IGuicedAuthenticationProvider:
public class MyAuthProvider implements IGuicedAuthenticationProvider {
@Override
public AuthenticationProvider getAuthenticationProvider() {
// Return your provider implementation
// e.g. UsernamePasswordCredentials-based, JWT, OAuth2, etc.
return myProvider;
}
}Register in module-info.java:
provides IGuicedAuthenticationProvider with MyAuthProvider;Multiple providers are combined via ChainAuth (ANY = first match wins, ALL = all must pass).
Register custom authorization providers via IGuicedAuthorizationProvider:
public class MyAuthzProvider implements IGuicedAuthorizationProvider {
@Override
public AuthorizationProvider getAuthorizationProvider() {
return myAuthorizationProvider;
}
}| Type | Scope | Description |
|---|---|---|
AuthenticationProvider |
Singleton | Primary provider (or ChainAuth if multiple) |
ChainAuth |
Singleton | The authentication chain |
AuthorizationProvider |
Singleton | Primary authorization provider |
Set<AuthorizationProvider> |
Multibinder | All registered authorization providers |
VertxContextPRNG |
Singleton | Shared PRNG (non-blocking, event-loop safe) |
KeyStoreOptions |
Instance | JVM keystore config (if configured) |
Set<PubSecKeyOptions> |
Multibinder | PEM key configs (if configured) |
public class LoginService {
@Inject private AuthenticationProvider authProvider;
public Future<User> login(String username, String password) {
return authProvider.authenticate(
new UsernamePasswordCredentials(username, password));
}
}Vert.x provides multiple authorization types:
// Role-based
RoleBasedAuthorization.create("admin").match(user);
// Permission-based
PermissionBasedAuthorization.create("printer:print").match(user);
// Wildcard permission
WildcardPermissionBasedAuthorization.create("printer:*").match(user);
// Logical combinations
AndAuthorization.create()
.addAuthorization(RoleBasedAuthorization.create("admin"))
.addAuthorization(PermissionBasedAuthorization.create("users:write"));
OrAuthorization.create()
.addAuthorization(RoleBasedAuthorization.create("admin"))
.addAuthorization(RoleBasedAuthorization.create("manager"));
NotAuthorization.create(RoleBasedAuthorization.create("guest"));Load authorizations onto a user:
@Inject private Set<AuthorizationProvider> authzProviders;
public Future<Void> loadAuthorizations(User user) {
List<Future<Void>> futures = authzProviders.stream()
.map(p -> p.getAuthorizations(user))
.toList();
return Future.all(futures).mapEmpty();
}// Access principal data (source identity)
JsonObject principal = user.principal();
// Access computed attributes
JsonObject attributes = user.attributes();
// Unified lookup (attributes first, then principal)
if (user.containsKey("sub")) {
String sub = user.get("sub");
}
// Token expiration (exp, iat, nbf with leeway)
boolean expired = user.expired();The shared VertxContextPRNG is event-loop safe and injectable:
@Inject private VertxContextPRNG prng;
String token = prng.nextString(32);
int randomInt = prng.nextInt();Configure via annotation or environment variables:
| Attribute | Variable | Default | System Property |
|---|---|---|---|
prngAlgorithm |
VERTX_AUTH_PRNG_ALGORITHM |
(system) | io.vertx.ext.auth.prng.algorithm |
prngSeedInterval |
VERTX_AUTH_PRNG_SEED_INTERVAL |
300000 ms | io.vertx.ext.auth.prng.seed.interval |
prngSeedBits |
VERTX_AUTH_PRNG_SEED_BITS |
64 | io.vertx.ext.auth.prng.seed.bits |
JVM KeyStore (pkcs12, jks):
@AuthOptions(keyStore = @AuthKeyStore(
path = "/path/to/keystore.pkcs12",
type = "pkcs12",
password = "changeit",
alias = "mykey",
aliasPassword = "keypass"
))Import PEM to PKCS12: openssl pkcs12 -export -in cert.pem -out keystore.pkcs12 -name myAlias -noiter -nomaciter
PEM Keys (PKCS8 format):
@AuthOptions(pubSecKeys = {
@AuthPubSecKey(algorithm = "RS256", path = "/path/to/public.pem"),
@AuthPubSecKey(algorithm = "ES256", buffer = "-----BEGIN PUBLIC KEY-----\n...")
})Convert to PKCS8: openssl pkcs8 -topk8 -inform PEM -in private.pem -out private_key.pem -nocrypt
| Property | Variable |
|---|---|
chainMode() |
VERTX_AUTH_CHAIN_MODE |
keyStore.path() |
VERTX_AUTH_KEYSTORE_PATH |
keyStore.type() |
VERTX_AUTH_KEYSTORE_TYPE |
keyStore.password() |
VERTX_AUTH_KEYSTORE_PASSWORD |
keyStore.alias() |
VERTX_AUTH_KEYSTORE_ALIAS |
keyStore.aliasPassword() |
VERTX_AUTH_KEYSTORE_ALIAS_PASSWORD |
pubSecKeys[n].algorithm() |
VERTX_AUTH_PUBSECKEY_n_ALGORITHM |
pubSecKeys[n].buffer() |
VERTX_AUTH_PUBSECKEY_n_BUFFER |
pubSecKeys[n].path() |
VERTX_AUTH_PUBSECKEY_n_PATH |
prngAlgorithm() |
VERTX_AUTH_PRNG_ALGORITHM |
prngSeedInterval() |
VERTX_AUTH_PRNG_SEED_INTERVAL |
prngSeedBits() |
VERTX_AUTH_PRNG_SEED_BITS |
leeway() |
VERTX_AUTH_LEEWAY |
IGuiceContext.instance()
└─ VertXPreStartup → builds Vertx, scans events, registers codecs
└─ VertxAuthPreStartup → scans @AuthOptions, discovers auth/authz providers,
builds ChainAuth, configures PRNG and key stores
└─ VerticleBuilder → deploys app verticles from @Verticle annotations
└─ VertxConsumersStartup → deploys one EventConsumerVerticle per address
| SPI | Purpose |
|---|---|
VertxConfigurator |
Customize VertxOptions during startup |
ClusterVertxConfigurator |
Configure clustering |
VerticleStartup |
Register custom verticles from Guice |
IGuicedAuthenticationProvider |
Contribute authentication providers to ChainAuth |
IGuicedAuthorizationProvider |
Contribute authorization providers |
com.guicedee.vertx
├── com.guicedee.client (SPI contracts)
├── com.guicedee.jsonrepresentation (JSON codec support)
├── io.vertx.core (Vert.x runtime)
├── io.vertx.auth.common (Authentication & Authorization)
├── io.vertx.mutiny (Mutiny bindings)
├── io.smallrye.mutiny (reactive streams)
├── io.github.classgraph (annotation scanning)
└── com.fasterxml.jackson.databind (JSON mapping)
Issues and pull requests are welcome — please add tests for new event patterns, codecs, or configurators.