The runtime engine for GuicedEE. This is the library you add to your application β it wires together the Client SPI, performs classpath scanning, creates the Guice injector, and manages the full startup/shutdown lifecycle.
Built on Google Guice Β· JPMS module com.guicedee.guicedinjection Β· Java 25+
<dependency>
<groupId>com.guicedee</groupId>
<artifactId>inject</artifactId>
</dependency>Gradle (Kotlin DSL)
implementation("com.guicedee:inject:2.4.0")// Register your module for classpath scanning
IGuiceContext.registerModuleForScanning.add("my.app");
// Bootstrap β scanning, SPI discovery, injector creation, lifecycle hooks
IGuiceContext.instance();
// Grab any managed instance
MyService svc = IGuiceContext.get(MyService.class);Provide a Guice module via JPMS + ServiceLoader:
public class AppModule extends AbstractModule
implements IGuiceModule<AppModule> {
@Override
protected void configure() {
bind(Greeter.class).to(DefaultGreeter.class);
}
}module my.app {
requires com.guicedee.guicedinjection;
provides com.guicedee.client.services.lifecycle.IGuiceModule
with my.app.AppModule;
}Inject a named Log4j2 logger into any Guice-managed class β no boilerplate, no static fields:
public class OrderService {
@InjectLogger("orders")
Logger log;
public void place(Order order) {
log.info("Placed order {}", order.id());
}
}| Attribute | Default | Purpose |
|---|---|---|
value |
declaring class name | Logger name |
level |
(none) | Optional level hint |
rollingFileName |
(none) | File name hint for rolling appenders |
fileName |
(none) | File name hint for file appenders |
The Log4JTypeListener and Log4JMembersInjector handle the wiring β they're registered automatically by ContextBinderGuice.
For setup outside of injection (e.g. main() or pre-startup hooks):
// ANSI-highlighted console (local dev)
LogUtils.addHighlightedConsoleLogger();
// Plain console at a specific level
LogUtils.addConsoleLogger(Level.INFO);
// Rolling file logger (100 MB / daily rollover)
LogUtils.addFileRollingLogger("my-app", "logs");
// Isolated logger with its own file
Logger auditLog = LogUtils.getSpecificRollingLogger(
"audit", "logs/audit", null, false
);When the
CLOUDenvironment variable is set, all layouts automatically switch to compact JSON for log aggregator ingestion.
JobService manages named virtual-thread executor pools with graceful shutdown:
JobService jobs = JobService.INSTANCE;
// Register and submit work
jobs.registerJob("import", 100);
jobs.addJob("import", () -> processFile(file));
// Scheduled polling
jobs.registerPollingJob("heartbeat", () -> ping(), 0, 30, TimeUnit.SECONDS);All pools are shut down automatically via IGuicePreDestroy when the context tears down.
GuiceContext uses ClassGraph 6.0.0, requiring Java 25 or newer.
The scanner explicitly enables the classpath and non-system modules. Metadata collection remains controlled by GuiceConfig;
visibility options also enable the metadata they require. Package configuration reads directly declared annotations, while
implementation and subclass discovery uses the transitive getAll... queries.
ClassGraph 6 does not load classes. Use com.guicedee.client.utils.ClassLoading.loadClass(classInfo) to resolve a boot-layer
module or the thread context classloader without running static initializers. For a custom classloader or module layer, pass
the application-owned loader to ClassLoading.loadClass(classInfo, loader). Keep that loader alive while using the discovered
classes. Metadata queries should use class names directly when no runtime Class is needed.
This is a source and binary API migration: rebuild libraries that expose or consume ClassGraph types together. The scanning
artifact brings classgraph-classpath, classgraph-vfs and classgraph-base transitively, with their own JPMS modules.
See the upstream porting guide
for the renamed metadata APIs and behavior changes.
Control the scan scope with SPI interfaces β implement and register via ServiceLoader / JPMS provides:
| SPI Interface | Method | Purpose |
|---|---|---|
IGuiceScanModuleInclusions |
includeModules() |
Modules to include |
IGuiceScanModuleExclusions |
excludeModules() |
Modules to exclude |
IGuiceScanJarInclusions |
includeJars() |
JAR filenames to include |
IGuiceScanJarExclusions |
excludeJars() |
JAR filenames to exclude |
public class MyExclusions
implements IGuiceScanModuleExclusions<MyExclusions> {
@Override
public Set<String> excludeModules() {
return Set.of("java.sql", "jdk.crypto.ec");
}
}| SPI Interface | Method | Purpose |
|---|---|---|
IPackageContentsScanner |
searchFor() |
Packages to include |
IPackageRejectListScanner |
exclude() |
Packages to exclude |
IPathContentsScanner |
searchFor() |
Resource paths to include |
IPathContentsRejectListScanner |
searchFor() |
Resource paths to exclude |
These fire during the ClassGraph scan and let you process matched resources inline:
| SPI Interface | Method | Match by |
|---|---|---|
IFileContentsScanner |
onMatch() |
Exact file name |
IFileContentsPatternScanner |
onMatch() |
Regex pattern |
public class ChangelogScanner implements IFileContentsScanner {
@Override
public Map<String, ResourceList.ByteArrayConsumer> onMatch() {
return Map.of("changelog.xml", (resource, bytes) -> {
// process matched resource
});
}
}| Setter | Default | Effect |
|---|---|---|
setFieldScanning(true) |
false |
Enable field-level scanning |
setAnnotationScanning(true) |
false |
Enable annotation scanning |
setMethodInfo(true) |
false |
Include method metadata |
setIgnoreFieldVisibility(true) |
false |
Scan non-public fields |
setIncludePackages(true) |
false |
Whitelist-only package scanning |
setVerbose(true) |
false |
Verbose ClassGraph output |
Configure via an IGuiceConfigurator SPI implementation.
IGuicePreStartup β ClassGraph scan β Injector created β IGuicePostStartup
β
IGuicePreDestroy (shutdown)
| Hook | Purpose |
|---|---|
IGuicePreStartup |
Runs before scanning and injector creation |
IGuicePostStartup |
Runs after the injector is ready |
IGuicePreDestroy |
Cleanup on shutdown (e.g. JobService) |
GuiceContext.destroy() stops the context exactly once for both direct injection
and GuiceApplication entry points. Concurrent callers wait for that cleanup;
same-thread reentrant calls return. The existing injector remains available to
cleanup hooks until they finish. Subsequent shutdown calls are harmless, and
injection after shutdown is rejected instead of restarting closed services.
Failed synchronous startup uses the same ordered, terminal cleanup path.
| IGuiceConfigurator | Configures GuiceConfig before scanning |
| Log4JConfigurator | Customizes Log4j2 appenders/patterns at startup |
flowchart LR
com_guicedee_guicedinjection["com.guicedee.guicedinjection"]
com_guicedee_guicedinjection --> com_guicedee_client["com.guicedee.client<br/>SPI contracts"]
com_guicedee_guicedinjection --> com_guicedee_vertx["com.guicedee.vertx<br/>Vert.x integration"]
com_guicedee_guicedinjection --> io_smallrye_config_core["io.smallrye.config.core<br/>MicroProfile Config"]
com_guicedee_guicedinjection --> org_apache_commons_lang3["org.apache.commons.lang3"]
Module name: com.guicedee.guicedinjection
The module declares uses for every scanner and lifecycle SPI, and provides default implementations for module/jar exclusions, the Guice context provider, and JRT URL handling.
In non-JPMS environments, META-INF/services discovery still works.
Issues and pull requests are welcome.