Zero-Overhead AI Inference in Legacy Java Applications
This project demonstrates embedding a Python-trained machine learning model directly into a Java 11 monolithic application. The model runs in-process with sub-millisecond inference latency, eliminating network overhead and external service dependencies.
- Sub-millisecond Inference - Direct Java method calls with latency under 1ms
- Zero Network Overhead - No HTTP/gRPC calls, no microservices
- Embedded Model - ONNX model packaged inside the application JAR
- Legacy Compatible - Runs on Java 11, suitable for legacy enterprise systems
- Simple Integration - Model as a resource, loaded at startup
- Java JDK 11 (or above)
- Apache Maven 3.6+
- Python 3.7+ (for model training only)
- API testing tool (Postman, cURL, or similar)
python create_model.pyGenerates model.onnx and places it in java-legacy-app/src/main/resources/.
cd java-legacy-app
mvn clean packagejava -jar target/java-embedded-ml-1.0-SNAPSHOT.jarServer starts at http://localhost:7070
Classify iris flower based on measurements.
Request Body:
{
"sepal_length": 5.1,
"sepal_width": 3.5,
"petal_length": 1.4,
"petal_width": 0.2
}Expected Response:
{
"input": {
"sepal_length": 5.1,
"sepal_width": 3.5,
"petal_length": 1.4,
"petal_width": 0.2
},
"predicted_class": 0,
"species": "Iris-setosa",
"latency_ms": "0.847"
}cURL Example:
curl -X POST http://localhost:7070/predict \
-H "Content-Type: application/json" \
-d '{"sepal_length":5.1,"sepal_width":3.5,"petal_length":1.4,"petal_width":0.2}'Check service status and model information.
Run test with known samples.
-
Create POST Request
- URL:
http://localhost:7070/predict - Method: POST
- Headers:
Content-Type: application/json
- URL:
-
Set Request Body
{ "sepal_length": 6.7, "sepal_width": 3.0, "petal_length": 5.0, "petal_width": 1.7 } -
Send Request
- Expected:
"species": "Iris-versicolor"
- Expected:
-
Test Health Endpoint
- URL:
http://localhost:7070/health - Method: GET
- URL:
JAVA_EMBEDDED_ML/
├── java-legacy-app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/com/demo/
│ │ │ │ ├── App.java # Main application, HTTP routes
│ │ │ │ ├── PredictionService.java # Model loader and predictor
│ │ │ │ └── SimpleOnnxTranslator.java # DJL translator for ONNX
│ │ │ └── resources/
│ │ │ └── model.onnx # Embedded ML model
│ │ └── test/java/com/demo/
│ │ └── PredictionServiceTest.java # Unit tests
│ └── pom.xml # Maven dependencies
├── create_model.py # Python training script
├── IRIS.csv # Training dataset
├── README.md
├── requirements.txt
└── .gitignore
| Component | Technology | Purpose |
|---|---|---|
| Inference Engine | Deep Java Library (DJL) | Java ML framework |
| Runtime | ONNX Runtime | High-performance C++ inference backend |
| Web Server | Javalin | Lightweight HTTP server |
| Build Tool | Maven | Dependency management and packaging |
| Model Format | ONNX | Universal ML model format |
| Training | Python + scikit-learn | Model development |
- Inference Latency: < 1ms (measured via
System.nanoTime()) - Startup Time: 2-3 seconds (includes model loading)
- Memory Overhead: ~50-150MB (DJL + ONNX Runtime + model)
- Model Size: ~50KB (RandomForest classifier)
cd java-legacy-app
mvn testpython create_model.py
mvn clean package
java -jar target/java-legacy-app-1.0-SNAPSHOT.jar- Train your model in Python (scikit-learn, PyTorch, TensorFlow, etc.)
- Export to ONNX format
- Replace
model.onnxinsrc/main/resources/ - Update
SimpleOnnxTranslator.javainput/output types if needed - Update
PredictionService.javaclass mappings
- Legacy System Modernization - Add AI to existing Java applications
- Low-Latency Requirements - Real-time inference with minimal overhead
- Edge Deployment - Run ML on devices with limited connectivity
- Cost Optimization - Eliminate separate ML infrastructure
- Regulatory Compliance - Keep sensitive data within existing boundaries
-
Training Phase (Python)
- Data scientist trains model using scikit-learn
- Model exported to
model.onnxusingskl2onnx
-
Build Phase (Maven)
model.onnxplaced insrc/main/resources/- Maven packages model inside JAR
-
Runtime Phase (Java)
PredictionServiceloads model from JAR resources on startup- DJL creates reusable
Predictorobject
-
Inference Phase (Java)
- HTTP endpoint receives request
- Calls
predictionService.predict()as direct method - Returns result with sub-millisecond latency
MIT License
This project demonstrates practical ML inference in legacy Java systems. The approach prioritizes simplicity: no microservices, no network calls, no operational overhead. Just a JAR dependency and an embedded model file delivering sub-millisecond predictions.