Table of Contents
MonoMorph is a fully automated refactoring tool that transforms monolithic Java applications into microservice architectures. Built on research from "Beyond Decomposition: A LLM-Powered Automated Approach to Refactoring Monoliths Into Microservices" [1], it bridges the gap between decomposition planning and executable microservices.
Its main objective is to replace the (previously) local interactions between classes with remote procedure calls (gRPC) while ensuring the consistency and correctness of the newly generated microservices.
Given your monolithic Java application and a decomposition plan, MonoMorph automatically:
- Analyzes your codebase to identify cross-service dependencies
- Determines the optimal refactoring strategy for each API class
- Generates gRPC-based communication infrastructure that replace local calls
- Creates independently deployable microservices
- Validates and corrects compilation errors
MonoMorph automates refactoring through a multi-stage workflow powered by specialized AI agents:
- Static Analysis - Analyzes the monolith using INRIA's Spoon to extract class relationships and dependencies
- Decision Making - LLM-powered agent determines the optimal refactoring approach (ID-based or DTO-based) for each API class using structured outputs
- Code Generation - Generates gRPC communication infrastructure with template-based prompting for consistency
- Validation & Correction - Compiles code in isolated Docker containers, with multi-turn LLM correction workflows and conversation rolling summaries to fix errors
Key Technologies: LangChain, LangGraph, Pydantic, Docker, gRPC, Protocol Buffers, Spoon
The main requirements are:
- Python 3.12 or higher
- Java Development Kit (JDK) 17
- Docker or a compatible containerization tool (e.g Podman, Orbstack)
- LLM API access (Openrouter, OpenAI, Google Gemini, or compatible providers)
Note: Currently, MonoMorph supports only Java applications built with Maven or Gradle.
- Clone the repo
git clone https://github.com/khaledsellami/monomorph.git
- Install MonoMorph as a Python module:
cd monomorph/ pip install -e .
- Set up your LLM API credentials in a
.envfile or export them as environment variables:export OPENROUTER_API_KEY="your-openrouter-api-key" # or export GEMINI_API_KEY="your-google-api-key"
MonoMorph requires the following inputs to perform automated refactoring:
The complete source code of your monolithic Java application. MonoMorph will automatically perform static analysis on the source code to extract structural dependencies and relationships.
your_monolith/
├── src/
│ ├── main/
│ │ └── java/
│ │ └── com/
│ │ └── example/
│ │ ├── User.java
│ │ ├── Order.java
│ │ └── ...
│ └── test/
│ └── ...
├── pom.xml (for Maven)
└── build.gradle (for Gradle)
A JSON file describing how you want to split the monolith into microservices. This file specifies which classes belong to which microservice.
{
"name": "my_decomposition",
"language": "java",
"granularity": "class",
"partitions": [
{
"name": "UserService",
"classes": ["com.example.User", "com.example.UserRepository"]
},
{
"name": "OrderService",
"classes": ["com.example.Order", "com.example.OrderRepository"]
}
]
}A Dockerfile (or reference Dockerfile from your monolith) that specifies the base image used to compile your application. MonoMorph uses this to understand the build environment and dependencies.
Example:
FROM maven:3.8.5-openjdk-17
WORKDIR /app
# MonoMorph only needs the base image specification
# The rest of the Dockerfile is not requiredfrom main import run_monomorph
# Run the refactoring process
monomorph_instance = run_monomorph(
app="MyApp",
app_source_code_path="/path/to/monolith/src",
decomposition_file="/path/to/decomposition.json",
package="com.example",
java_version="11", # your Java version
build_tool="maven", # or "gradle"
original_dockerfile_path="/path/to/Dockerfile",
out_path="./output"
)-
Required:
app: Application nameapp_source_code_path: Path to monolith source codedecomposition_file: Path to decomposition JSONpackage: Your application's Java package namejava_version: Your application's Java versionbuild_tool: "maven" or "gradle"original_dockerfile_path: Path to the Dockerfile example
-
Optional:
out_path: Output directory to save refactored microservices and other artifacts (default: "./data/monomorph-output")refact_approach: "Hybrid" (default) or "ID-only"refact_model: LLM for code generation agent (default: "gemini-2.5-pro")decision_model: LLM for decision (ID or DTO) making agent (default: "gemini-2.5-pro")correction_model: LLM for error correction agent (default: "gemini-2.5-pro")
The refactored output will be generated in the following structure:
{out_path}/
└── MyApp/
├── refactored_code/
│ └── MyApp-{timestamp}-{run_id}/
│ ├── UserService/
│ │ ├── src/
│ │ ├── pom.xml
│ │ └── REFACTORING_REPORT.md
│ ├── OrderService/
│ │ ├── src/
│ │ ├── pom.xml
│ │ └── REFACTORING_REPORT.md
│ └── REFACTORING_REPORT.md
├── llm_responses/
├── llm_checkpoints/
├── refactoring_logs.log
└── metadata.json
Enable caching and checkpointing to reuse LLM responses and reduce costs (useful for experiments and debugging):
run_monomorph(
# ...other params...
use_llm_cache=True,
llm_cache_path=".langchain.db",
checkpoint_load=True,
checkpoint_save=True,
llm_checkpoints_path="./checkpoints",
run_id="specific-run-id" # Resume specific run
)Choose different LLMs for different tasks:
run_monomorph(
# ...other params...
refact_model="gemini-2.5-pro", # Code generation
parser_model="ministral-8b", # Response parsing
decision_model="gemini-2.5-pro", # Decision making
correction_model="gemini-2.5-pro", # Error correction
fallback_model="gemini-2.5-pro" # Fallback option (in case of rate limits or errors)
)An example monolithic Java application along with a sample decomposition plan and Dockerfile template can be found in the examples/ directory of this repository. You can use this example to test and explore MonoMorph's capabilities.
Make sure to clone the following specific commit of the repository to ensure compatibility with the decomposition file:
mkdir -p ./examples/spring-petclinic
git clone https://github.com/spring-projects/spring-petclinic.git
mv spring-petclinic ./examples/spring-petclinic/monolithic-source-code
cd examples/spring-petclinic/monolithic-source-code
git reset --hard 1079767adc4576db0804c6d615c209c3d1cf351f
git clean -dfpython example.pyKhaled Sellami - khaledsellami - khaled.sellami.1@ulaval.ca
- 0.2.0
- Initial Public Release
If this work was useful for your research, please consider citing it:
@INPROCEEDINGS{monomorph,
author={Sellami, Khaled and Jebbar, Oussama and Gannoun, Ayyoub and Saied, Mohamed Aymen},
booktitle={2025 25th International Conference on Software Quality, Reliability and Security (QRS)},
title={Beyond Decomposition: A LLM-Powered Automated Approach to Refactoring Monoliths Into Microservices},
year={2025},
volume={},
number={},
pages={68-77},
keywords={Codes;Large language models;Source coding;Microservice architectures;Software quality;Benchmark testing;Reliability engineering;Software reliability;Complexity theory;Contracts;Microservices Migration;Refactoring;Decomposition;Large Language Models;Remote Procedural Calls},
doi={10.1109/QRS65678.2025.00018}
}
Distributed under the GNU GPL-3.0 License. See LICENSE for more information.
[1] Sellami, Khaled, Oussama Jebbar, Ayyoub Gannoun, and Mohamed Aymen Saied. 'Beyond Decomposition: A LLM-Powered Automated Approach to Refactoring Monoliths Into Microservices'. In 2025 25th International Conference on Software Quality, Reliability and Security (QRS), 68-77, 2025. https://doi.org/10.1109/QRS65678.2025.00018.