Skip to main content

Automation for Java/JBoss to Spring Boot/Quarkus migration with minimal code loss.

Project description

Legacy Migration Toolkit

Python-based automation for Java/JBoss to Microservices migration with GitHub Copilot.

Goal: build a reusable migration script that helps convert JBoss code to Spring Boot with minimal code loss and minimal developer pain, especially when using Copilot or Cursor.

Solves the most redundant problem in enterprise Java: migrating complex legacy EJB/JBoss code to Spring Boot/Quarkus microservices without losing business logic.

The Problem

Challenge How This Toolkit Solves It
Copilot loses context on large legacy files Chunked prompts — one method per prompt, not entire classes
Code loss during migration (methods, logic, validations) Automated code loss detection — compares legacy vs migrated code
Tedious manual file-by-file comparison Hash-based fingerprinting — detects body changes, missing methods, annotation drift
No systematic migration approach 5-phase workflow — analyze, plan, generate, detect, repair
JEE annotations not properly translated Annotation mapping — EJB→Spring, JAX-RS→Spring MVC, CDI→Spring DI

Quick Start

# Install (pip or pipx)
pip install legacy-migration-toolkit
# or
pipx install legacy-migration-toolkit

# No external dependencies needed — pure Python 3.8+ standard library

# Run the demo (creates sample legacy + migrated files with intentional code losses)
legacy-migration --demo

# Migrate your actual legacy codebase (interactive, class-by-class)
legacy-migration --legacy /path/to/legacy/src/main/java --migrated /path/to/new/src/main/java

# Fix detected losses when you're ready
python3 fix_issues.py

The 5-Phase Workflow

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   Phase 1: ANALYZE                                              │
│   ├─ Parse all legacy .java files                               │
│   ├─ Extract: classes, methods, fields, annotations, imports    │
│   ├─ Classify: EJB, JPA, JAX-RS, CDI, Servlet, POJO            │
│   └─ Fingerprint: SHA-256 hash of each method body              │
│                                                                 │
│   Phase 2: PLAN                                                 │
│   ├─ Prioritize: Entities → Interfaces → Services → REST → MDB │
│   ├─ Dependency analysis: which classes are most depended-on    │
│   └─ Copilot strategy: CHUNKED vs HYBRID vs FULL CLASS          │
│                                                                 │
│   Phase 3: GENERATE (Copilot Prompts)                           │
│   ├─ Class scaffold prompt (structure + injections)             │
│   ├─ Per-method prompts (one method at a time!)                 │
│   ├─ Test generation prompts                                    │
│   └─ Each prompt includes verification checklist                │
│                                                                 │
│   ══════ Developer uses Copilot with generated prompts ══════   │
│                                                                 │
│   Phase 4: DETECT (Code Loss Detection)                         │
│   ├─ Missing classes, methods, fields                           │
│   ├─ Signature changes (params, return types)                   │
│   ├─ Body changes (>50% size diff = suspicious)                 │
│   ├─ Annotation drift (EJB→Spring mapping validation)           │
│   └─ Severity: CRITICAL / HIGH / MEDIUM / LOW                   │
│                                                                 │
│   Phase 5: REPAIR (Fix Prompts)                                 │
│   ├─ Targeted Copilot prompts for each detected loss            │
│   └─ Repeat Phase 4→5 until zero critical/high issues           │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

How to Use with GitHub Copilot

Strategy: Chunk, Don't Dump

The #1 mistake developers make is pasting an entire 500-line EJB into Copilot and asking "convert this to Spring Boot." Copilot will:

  • Lose context halfway through
  • Skip methods it considers "obvious"
  • Drop error handling, null checks, and edge cases
  • Miss injection points

Instead, this toolkit generates focused, single-concern prompts.

Recommended Copilot Workflow

1. Run:  python3 run_migration.py analyze --legacy ./src/main/java
2. Open: reports/03_copilot_prompts/{ClassName}/
3. For each class:
   a. Open 01_scaffold_{ClassName}.txt → paste into Copilot Chat
   b. Copilot generates the class skeleton
   c. Open 02_method_{ClassName}_{methodName}_*.txt → paste one at a time
   d. Copilot fills in each method with full context
   e. Check off the verification checklist at the bottom of each prompt
4. Run:  python3 run_migration.py detect --legacy ./old --migrated ./new
5. Open: reports/04_code_loss_report.md → review all findings
6. Start Copilot/Cursor with `reports/AGENT_MIGRATION_INSTRUCTIONS.md`, then use prompts in `reports/03_copilot_prompts/`.
7. Decide when to fix losses. You can fix immediately with reports/05_fix_prompts/ or defer and continue migrating, then run fix_issues.py later.
8. Repeat steps 4-7 until the report shows zero CRITICAL/HIGH issues

Class Mapping Overrides

If you renamed classes during migration, provide a mapping file:

{
    "com.example.legacy.OrderBean": "com.example.service.OrderService",
    "com.example.legacy.OrderDAOImpl": "com.example.repository.OrderRepository"
}
python3 run_migration.py detect \
    --legacy ./old/src --migrated ./new/src \
    --class-map ./class_mapping.json

What Gets Detected

Detection Type Severity Example
Missing Class CRITICAL OrderService has no equivalent in new code
Missing Method CRITICAL cancelOrder() entirely missing
Signature Change HIGH createOrder(Request)createOrder(Customer, List)
Body Change (>50% diff) HIGH Method went from 40 lines to 15 lines
Missing Injection HIGH @EJB InventoryService not wired in new code
Annotation Drift MEDIUM @Stateless not mapped to @Service
Interface Dropped MEDIUM implements Serializable removed
Body Change (minor) LOW Small refactoring detected

Project Structure

legacy-migration-toolkit/
├── run_migration.py              # CLI entry point
├── requirements.txt              # No external deps needed
├── src/
│   ├── analyzers/
│   │   └── java_parser.py        # Parses legacy Java files
│   ├── detectors/
│   │   └── code_loss_detector.py # Compares legacy vs migrated
│   ├── generators/
│   │   └── copilot_prompt_generator.py  # Creates Copilot prompts
│   └── orchestrator/
│       └── migration_workflow.py # Ties everything together
├── examples/
│   ├── legacy_code/              # Sample JBoss EJB code
│   └── migrated_code/            # Sample Spring Boot code (with losses)
├── reports/                      # Generated reports land here
└── templates/                    # Prompt templates

Supported Migrations

From (Legacy) To (Target)
EJB @Stateless Spring @Service
EJB @Stateful Spring @Service + @SessionScope
EJB @MessageDriven Spring @JmsListener
JAX-RS @Path Spring @RestController
JPA @Entity JPA @Entity (javax→jakarta)
CDI @Inject Spring @Autowired / Constructor Injection
Servlet Spring @Controller

Target frameworks: Spring Boot (default), Quarkus, Micronaut

Additional Suggestions

Beyond this toolkit, consider these approaches for large-scale migrations:

  1. Strangler Fig Pattern: Don't migrate everything at once. Wrap legacy services behind a facade and replace them one by one.

  2. Contract-First Testing: Before migration, write integration tests against your legacy REST endpoints. After migration, run the same tests against the new code. If tests pass, the migration preserved behavior.

  3. Copilot Custom Instructions: In your GitHub Copilot settings, add a custom instruction like:

    "When converting Java EE code to Spring Boot, always preserve all null checks, error handling, and business validations. Never simplify or omit edge case handling. Use constructor injection instead of field injection."

  4. Batch Processing with Copilot CLI: For teams, use gh copilot CLI to script prompt execution across multiple files.

  5. Version Control Each Phase: Commit after each phase completes. Tag commits like migration/phase-1-entities, migration/phase-2-services. This gives rollback points.

Packaging (pip)

Local install (dev)

# In repo root
python3 -m venv .venv
.venv/bin/python setup.py develop
legacy-migration --help

Build and publish to PyPI

python3 -m pip install build twine
python3 -m build
twine upload dist/*

Update the package

  1. Bump the version in pyproject.toml and setup.py.
  2. Rebuild and republish (python3 -m build, then twine upload dist/*).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

legacy_migration_toolkit-0.4.0.tar.gz (45.4 kB view details)

Uploaded Source

File details

Details for the file legacy_migration_toolkit-0.4.0.tar.gz.

File metadata

File hashes

Hashes for legacy_migration_toolkit-0.4.0.tar.gz
Algorithm Hash digest
SHA256 398bbc2781a05d799db821c3f1600efa33034fd08a3443cfd40c5754ad0f343e
MD5 cc78a67591aae0f3b05ffc8a4edc44ea
BLAKE2b-256 0b52745630056e49e2c2645d605c255f5effe968409966181f3a54a8ba773edd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page