GuicedEE Client
The client SPI library — defines the contracts that all GuicedEE modules program against without pulling in the full runtime.
Core Concept
This library provides the interfaces and annotations for the GuicedEE lifecycle. Application code and library modules depend on client to register hooks, access the injector, and define scoping — without coupling to the runtime engine in inject.
Required Flow
- Add
com.guicedee:clientdependency. - Register your module for classpath scanning:
IGuiceContext.registerModuleForScanning.add("my.app"); IGuiceContext context = IGuiceContext.instance(); Injector injector = context.inject(); - Register hooks with JPMS
provides:module my.app { requires com.guicedee.client; provides com.guicedee.client.services.lifecycle.IGuiceModule with my.app.AppModule; }
Lifecycle Hook Interfaces
All hooks extend IDefaultService<J> (CRTP); override sortOrder() when a custom execution order is needed. IGuiceModule additionally declares enabled() (default true). IDefaultService, startup, shutdown, and configurator hooks do not declare enabled(); gate their work inside the hook body.
| Interface | When | Purpose |
|---|---|---|
| IGuiceConfigurator<J> | First | Configure GuiceConfig before scanning |
| IGuicePreStartup<J> | After scan, before injector | Pre-startup tasks, returns List<Future<Boolean>> |
| IGuiceModule<J> | During injector creation | Standard Guice AbstractModule |
| IGuicePostStartup<J> | After injector ready | Post-startup tasks, returns List<Uni<Boolean>> |
| IGuicePreDestroy<J> | Shutdown or startup rollback | Cleanup in ascending shutdownSortOrder(), with class-name tie-breaking |
Key Classes
| Class | Purpose |
|---|---|
| IGuiceContext | Singleton access to injector and context |
| IDefaultService | Base for all SPI hooks (CRTP) with sortOrder() (default 100; some hooks override the default, e.g. IGuicePostStartup = 50) |
| Environment | Canonical environment-variable / system-property resolver — always use this instead of System.getenv/System.getProperty |
| CallScope / CallScopeProperties | Request-scoped injection context |
| IJsonRepresentation | Jackson ObjectMapper configuration contract |
Environment Variables — always use Environment
Never call System.getenv(...) / System.getProperty(...) directly, and never write a local env(...)/getProperty(...) helper. Resolve every environment variable and system property through com.guicedee.client.Environment:
import com.guicedee.client.Environment;
// name, default — returns the resolved value (never null; empty string if no default)
String enterprise = Environment.getSystemPropertyOrEnvironment("AM_ENTERPRISE_NAME", "NE1 World");
boolean enabled = Boolean.parseBoolean(
Environment.getSystemPropertyOrEnvironment("AM_INSTALL_ENABLED", "true"));
Environment.getSystemPropertyOrEnvironment(name, default) resolves with this precedence (highest first):
- System property (
-Dname=value) - OS environment variable (
name, then the upper-cased/underscoredNAMEvariant) .env.localfile (local overrides, typically git-ignored).envfile (shared defaults, may be committed)- the provided default (with
${...}placeholders resolved)
Environment.getProperty(name, default) is an alias of getSystemPropertyOrEnvironment with the same precedence, .env.local/.env lookup, and placeholder resolution. Use the canonical getSystemPropertyOrEnvironment spelling in new code. Other helpers include Environment.resolvePlaceholders(value) for ${VAR:-default} strings and Environment.reloadDotEnv() for tests. All string config attributes therefore support ${ENV_VAR} placeholders for free.
Non-Negotiable Constraints
- Module must
requires com.guicedee.client;. - All SPI implementations must be dual-registered (
module-info.java+META-INF/services/). sortOrder()controls execution order — lower runs first.IGuiceModule.enabled()controls module enablement; other hooks gate work inside their method.- Lifecycle hooks are grouped by
sortOrder()— all futures in a group must complete before the next group. IGuicePreStartup.onStartup()returnsList<Future<Boolean>>— uses Vert.xio.vertx.core.Future.IGuicePostStartup.postLoad()returnsList<Uni<Boolean>>— uses Mutinyio.smallrye.mutiny.Uni.- These are DIFFERENT types — do not confuse them.
- Resolve env vars/system properties only through
Environment.getSystemPropertyOrEnvironment(name, default)— neverSystem.getenv/System.getPropertyand never a hand-rolledenv(...)helper.
Call scopes and lifecycle ownership
CallScoper carries JVM-local request values through supported callbacks and Mutiny continuations. IOnCallScopeEnter and IOnCallScopeExit are per-call hooks; a startup-only setting does not configure each request. Dual-register implementations in JPMS and META-INF/services. Scope values and correlation IDs do not authenticate another process or grant access to a distributed resource.
Use Integer sortOrder() for startup and Integer shutdownSortOrder() for teardown; the latter defaults to sortOrder(). IGuiceContext.destroy() is terminal: cleanup may resolve existing bindings, but must not bootstrap a replacement injector.
JPMS dependency names
When adding requires directives, use the correct module names:
| Maven Artifact | JPMS Module Name |
|---|---|
| io.vertx:vertx-core | io.vertx.core |
| io.vertx:vertx-web | io.vertx.web |
| io.vertx:vertx-web-client | io.vertx.web.client |
| io.vertx:vertx-service-resolver | io.vertx.serviceresolver |
| io.smallrye.reactive:mutiny | io.smallrye.mutiny |
| io.github.classgraph:classgraph | io.github.classgraph |
| com.google.inject:guice | com.google.guice |