| name | judo-runtime:module-setup |
| description | Guide to setting up JudoDefaultModule, JudoDefaultModuleConfiguration, JudoModelLoader, and ComponentScanModule for JUDO applications. Use when bootstrapping a new JUDO application, configuring runtime options, or loading JUDO models. |
| metadata | {"author":"BlackBelt Technology","version":"${project.version}"} |
JUDO Guice Module Setup
Guide for configuring and bootstrapping JUDO applications with Google Guice.
Overview
The JUDO Guice integration provides a complete dependency injection setup through several key components:
- JudoDefaultModule: Main Guice module that wires all JUDO components
- JudoDefaultModuleConfiguration: Configuration options for the runtime
- JudoModelLoader: Loads JUDO metamodels (ASM, RDBMS, Expression, etc.)
- ComponentScanModule: Automatic component discovery via classpath scanning
Architecture
graph TB
subgraph "Application Bootstrap"
App[Application]
Injector[Guice Injector]
end
subgraph "JUDO Modules"
JDM[JudoDefaultModule]
CSM[ComponentScanModule]
DBM[Database Module<br/>HSQLDB/PostgreSQL]
end
subgraph "Configuration"
JML[JudoModelLoader]
JDMC[JudoDefaultModuleConfiguration]
end
subgraph "Runtime Services"
DAO[DAO]
Dispatcher[Dispatcher]
Security[Security]
Validators[Validators]
end
App --> Injector
Injector --> JDM
Injector --> CSM
Injector --> DBM
JDM --> JDMC
JDMC --> JML
JDM --> DAO
JDM --> Dispatcher
JDM --> Security
JDM --> Validators
JudoModelLoader
JudoModelLoader is responsible for loading all JUDO metamodels required by the runtime.
Loading from Classpath
JudoModelLoader models = JudoModelLoader.loadFromClassloader(
"myapp",
getClass().getClassLoader(),
HsqldbDialect.INSTANCE,
true,
false
);
Loading from Directory
JudoModelLoader models = JudoModelLoader.loadFromDirectory(
"myapp",
new File("/path/to/models"),
PostgresqlDialect.INSTANCE,
false
);
Loading from URI
JudoModelLoader models = JudoModelLoader.loadFromURL(
"myapp",
modelDirectoryUri,
HsqldbDialect.INSTANCE,
true,
true
);
Model Files Expected
The loader expects these model files in the directory/classpath:
| File Pattern | Description |
|---|
{name}-asm.model | Abstract Syntax Model |
{name}-rdbms_{dialect}.model | RDBMS Model for specific dialect |
{name}-measure.model | Measurement/unit definitions |
{name}-expression.model | Expression definitions |
{name}-liquibase_{dialect}.changelog.xml | Database schema |
{name}-asm2rdbms_{dialect}.model | ASM to RDBMS trace |
{name}-keycloak.model | Keycloak configuration (optional) |
Creating Empty Models (Testing)
JudoModelLoader models = JudoModelLoader.empty();
JudoDefaultModuleConfiguration
Configuration class using the builder pattern with sensible defaults.
Key Configuration Options
| Option | Default | Description |
|---|
judoModelLoader | null | Required: The loaded models |
bindModelHolder | true | Bind JudoModelLoader to injector |
rdbmsDaoOptimisticLockEnabled | true | Enable optimistic locking |
rdbmsDaoChunkSize | 1000 | Batch operation chunk size |
dispatcherEnableDefaultValidation | true | Enable payload validation |
dispatcherCaseInsensitiveLike | false | Case-insensitive LIKE queries |
dispatcherTrimString | false | Trim whitespace from strings |
metricsCollectorEnabled | false | Enable metrics collection |
identifierSignerSecret | auto-generated | Secret for signing identifiers |
Example Configuration
JudoDefaultModuleConfiguration config = JudoDefaultModuleConfiguration.builder()
.judoModelLoader(models)
.rdbmsDaoOptimisticLockEnabled(true)
.rdbmsDaoChunkSize(500)
.dispatcherEnableDefaultValidation(true)
.dispatcherCaseInsensitiveLike(true)
.metricsCollectorEnabled(true)
.metricsCollectorConsumer(metrics -> log.info("Metrics: {}", metrics))
.identifierSignerSecret("my-secure-secret-key")
.build();
JudoDefaultModule
The main Guice module that configures all JUDO runtime bindings.
Basic Setup
JudoDefaultModule module = JudoDefaultModule.builder()
.configuration(config)
.build();
JudoDefaultModule module = JudoDefaultModule.builder()
.judoModelLoader(models)
.rdbmsDaoOptimisticLockEnabled(true)
.dispatcherEnableDefaultValidation(true)
.build();
Creating the Injector
Injector injector = Guice.createInjector(
module,
new HsqldbModule(),
new ComponentScanModule("com.myapp", Singleton.class)
);
Injecting to External Object
MyApplication app = new MyApplication();
JudoDefaultModule module = JudoDefaultModule.builder()
.injectModulesTo(app)
.judoModelLoader(models)
.build();
ComponentScanModule
Automatically discovers and binds classes annotated with specific annotations.
Basic Usage
ComponentScanModule scanModule = new ComponentScanModule(
"com.myapp.services",
Singleton.class,
Named.class
);
Injector injector = Guice.createInjector(
judoModule,
scanModule
);
How It Works
sequenceDiagram
participant App as Application
participant CSM as ComponentScanModule
participant Ref as Reflections
participant Guice
App->>Guice: createInjector(ComponentScanModule)
Guice->>CSM: configure()
CSM->>Ref: Scan package for annotations
Ref-->>CSM: Set of annotated classes
loop For each class
CSM->>Guice: bind(class)
end
Common Use Cases
new ComponentScanModule("com.myapp", Singleton.class)
new ComponentScanModule("com.myapp",
Service.class,
Repository.class,
Singleton.class
)
Complete Bootstrap Example
public class MyApplication {
public static void main(String[] args) throws Exception {
JudoModelLoader models = JudoModelLoader.loadFromClassloader(
"myapp",
MyApplication.class.getClassLoader(),
HsqldbDialect.INSTANCE,
true,
false
);
JudoDefaultModule judoModule = JudoDefaultModule.builder()
.judoModelLoader(models)
.rdbmsDaoOptimisticLockEnabled(true)
.dispatcherEnableDefaultValidation(true)
.metricsCollectorEnabled(true)
.build();
HsqldbModule hsqldbModule = HsqldbModule.builder()
.databasePath("./db/myapp")
.build();
Injector injector = Guice.createInjector(
judoModule,
hsqldbModule,
new ComponentScanModule("com.myapp", Singleton.class)
);
Dispatcher dispatcher = injector.getInstance(Dispatcher.class);
DAO dao = injector.getInstance(DAO.class);
}
}
Production Configuration
For production deployments with PostgreSQL:
PostgresqlModule postgresModule = PostgresqlModule.builder()
.jdbcUrl("jdbc:postgresql://localhost:5432/myapp")
.username("myapp_user")
.password("secure_password")
.build();
JudoDefaultModule judoModule = JudoDefaultModule.builder()
.judoModelLoader(models)
.rdbmsDaoOptimisticLockEnabled(true)
.rdbmsDaoChunkSize(1000)
.dispatcherEnableDefaultValidation(true)
.identifierSignerSecret(System.getenv("JUDO_SIGNER_SECRET"))
.metricsCollectorEnabled(true)
.metricsCollectorVerbose(false)
.build();
Injector injector = Guice.createInjector(
judoModule,
postgresModule
);
See Also
judo-runtime:dependency-injection - Understanding and extending DI bindings
judo-runtime-core-guice-hsqldb - HSQLDB integration module
judo-runtime-core-guice-postgresql - PostgreSQL integration module
judo-runtime-core-guice-testkit - Testing utilities