| name | judo-backend-docs |
| description | Backend development guide for JUDO applications. Covers custom operations, interceptors, validators, data access, and error handling. |
| disable-model-invocation | false |
| user-invocable | false |
| agent | general-purpose |
Backend Development Guide
Overview
Backend development in northwind involves implementing custom business logic in Java while leveraging the JUDO-generated SDK and runtime infrastructure.
Note: Throughout this document, northwind refers to the application name from judo.properties (app_name property). Package names, file paths, and generated artifacts use this value.
Key Concepts
- Model-Driven Development: The application's structure, including entities, services, and APIs, is defined in high-level models. All development work is grounded in these models.
- Code Generation: The JUDO platform automatically generates a significant portion of the codebase (like SDKs and REST endpoints) from the models. This ensures consistency and reduces boilerplate code.
- Custom Implementation: Your primary focus as a developer is to implement custom business logic in specific, designated directories (
application/app/, application/interceptors/). These areas are protected from the code generation process.
- Checksum Protection: To prevent accidental edits to generated files, a checksum system is in place. Modifying a generated file will cause the build to fail unless it's explicitly ignored.
- Hot Deployment: For rapid development cycles, changes to custom code can be deployed to a running Karaf instance without a full server restart.
Architecture
Code Generation vs Custom Implementation
Generated (Do Not Edit Directly):
- SDK API interfaces (
application/sdk/)
- Internal SDK wrappers (
application/internal/)
- REST API endpoints (
application/rest/)
- Entity runtime models (from ASM)
Custom Implementation (Edit Here):
- Business logic operations (
application/app/)
- Request/response interceptors (
application/interceptors/)
- Custom validators and processors
Code Generation and Checksum Protection
How Generation Works:
- All generated files are tracked by checksum in
.generated-files (located in generator output directories)
- Files NOT in
.generator-ignore will be regenerated on ./judo.sh build or ./judo.sh generate
- Checksum validation: Before overwriting, the generator checks if a file was manually edited
- If file was edited (checksum mismatch) → ❌ Build FAILS with error
- If file unchanged → ✅ File is regenerated normally
When You Must Edit Generated Files:
Before editing a generated file directly, check the two extension mechanisms offered by the template — they keep the file under generator control and survive future template upgrades:
- Generator parameter — some aspects of generation are controlled via
generator-parameter.properties (see deployment/build-process.md → When to Check Templates Instead of Patching).
- Fragment extension point — most
pom.xml, feature.xml, and similar files expose named fragments you can fill in by dropping a file under application/generator-overrides/<fragment-path>. Look for paired marker comments such as
See deployment/build-process.md → Extending Generated Files via Fragment Overrides for the full list and a worked example.
Only if neither mechanism offers a hook should you fall back to editing the generated file directly. This is NOT the preferred way, but when necessary:
- Edit the generated file with your changes
- Add to
.generator-ignore to protect it from regeneration
echo "application/sdk/src/main/java/[PACKAGE]/[GeneratedFile].java" >> .generator-ignore
- Place the entry in
.generator-ignore near related overrides (it's used like .gitignore)
Handling Checksum Errors:
If you get checksum errors due to code formatting changes (e.g., after git checkout or IDE auto-format in dev mode):
./judo.sh generate -i
./judo.sh build -i
Checksum File Locations:
.generated-files - In each generator output directory
- Format: Tracks file paths and their checksums
Prerequisites
Required Tool Versions
This project uses SDKMAN for version management. Required versions are specified in .sdkmanrc:
java=21.0.7-zulu
maven=3.9.10
mvnd=1.0.2
Setup:
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
echo "sdkman_auto_env=true" >> ~/.sdkman/etc/config
cd [project-name]
sdk env install
java -version
mvn -version
How It Works:
.sdkmanrc is generated by ./judo.sh generate-root command
- When
sdkman_auto_env=true, SDKMAN automatically switches to project versions when you enter the directory
./judo.sh script automatically installs required versions if missing
Maven Daemon (mvnd): Optional but recommended for faster builds
mvnd clean install
Project Structure
application/
├── sdk/ # Generated API interfaces
│ └── src/main/java/[PACKAGE]/
│ └── [Entity]Dao.java, [Entity]Service.java
├── internal/ # Generated SDK wrappers (binds custom to runtime)
├── app/ # ✏️ CUSTOM OPERATIONS HERE
│ └── src/main/java/[PACKAGE]/
│ └── Custom[Entity]ServiceImpl.java
├── interceptors/ # ✏️ CUSTOM INTERCEPTORS HERE
│ └── src/main/java/[PACKAGE]/
│ ├── LogAuthenticationInterceptor.java
│ └── LogOperationCallInterceptor.java
└── rest/ # Generated JAX-RS endpoints
└── resources/
Note: Package structure is generated from the model and typically follows patterns like hu.blackbelt.model.northwind or party.mkkp.northwind.
See Also