legacy-migration-toolkit 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- legacy_migration_toolkit-0.4.0/LICENSE +21 -0
- legacy_migration_toolkit-0.4.0/MANIFEST.in +8 -0
- legacy_migration_toolkit-0.4.0/PKG-INFO +241 -0
- legacy_migration_toolkit-0.4.0/README.md +207 -0
- legacy_migration_toolkit-0.4.0/fix_issues.py +259 -0
- legacy_migration_toolkit-0.4.0/legacy_migration_toolkit.egg-info/PKG-INFO +241 -0
- legacy_migration_toolkit-0.4.0/legacy_migration_toolkit.egg-info/SOURCES.txt +23 -0
- legacy_migration_toolkit-0.4.0/legacy_migration_toolkit.egg-info/dependency_links.txt +1 -0
- legacy_migration_toolkit-0.4.0/legacy_migration_toolkit.egg-info/entry_points.txt +2 -0
- legacy_migration_toolkit-0.4.0/legacy_migration_toolkit.egg-info/top_level.txt +3 -0
- legacy_migration_toolkit-0.4.0/pyproject.toml +31 -0
- legacy_migration_toolkit-0.4.0/run_migration.py +844 -0
- legacy_migration_toolkit-0.4.0/setup.cfg +4 -0
- legacy_migration_toolkit-0.4.0/setup.py +17 -0
- legacy_migration_toolkit-0.4.0/src/__init__.py +2 -0
- legacy_migration_toolkit-0.4.0/src/analyzers/__init__.py +0 -0
- legacy_migration_toolkit-0.4.0/src/analyzers/java_parser.py +497 -0
- legacy_migration_toolkit-0.4.0/src/detectors/__init__.py +0 -0
- legacy_migration_toolkit-0.4.0/src/detectors/code_loss_detector.py +631 -0
- legacy_migration_toolkit-0.4.0/src/generators/__init__.py +0 -0
- legacy_migration_toolkit-0.4.0/src/generators/agent_report_generator.py +384 -0
- legacy_migration_toolkit-0.4.0/src/generators/class_migrator.py +384 -0
- legacy_migration_toolkit-0.4.0/src/generators/copilot_prompt_generator.py +554 -0
- legacy_migration_toolkit-0.4.0/src/orchestrator/__init__.py +0 -0
- legacy_migration_toolkit-0.4.0/src/orchestrator/migration_workflow.py +539 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Divya Bairavarasu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: legacy-migration-toolkit
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Automation for Java/JBoss to Spring Boot/Quarkus migration with minimal code loss.
|
|
5
|
+
Author: Divya Bairavarasu
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Divya Bairavarasu
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Classifier: Programming Language :: Python :: 3
|
|
29
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
30
|
+
Classifier: Operating System :: OS Independent
|
|
31
|
+
Requires-Python: >=3.8
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
License-File: LICENSE
|
|
34
|
+
|
|
35
|
+
# Legacy Migration Toolkit
|
|
36
|
+
|
|
37
|
+
**Python-based automation for Java/JBoss to Microservices migration with GitHub Copilot.**
|
|
38
|
+
|
|
39
|
+
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.
|
|
40
|
+
|
|
41
|
+
Solves the most redundant problem in enterprise Java: migrating complex legacy EJB/JBoss code to Spring Boot/Quarkus microservices **without losing business logic**.
|
|
42
|
+
|
|
43
|
+
## The Problem
|
|
44
|
+
|
|
45
|
+
| Challenge | How This Toolkit Solves It |
|
|
46
|
+
|-----------|---------------------------|
|
|
47
|
+
| Copilot loses context on large legacy files | **Chunked prompts** — one method per prompt, not entire classes |
|
|
48
|
+
| Code loss during migration (methods, logic, validations) | **Automated code loss detection** — compares legacy vs migrated code |
|
|
49
|
+
| Tedious manual file-by-file comparison | **Hash-based fingerprinting** — detects body changes, missing methods, annotation drift |
|
|
50
|
+
| No systematic migration approach | **5-phase workflow** — analyze, plan, generate, detect, repair |
|
|
51
|
+
| JEE annotations not properly translated | **Annotation mapping** — EJB→Spring, JAX-RS→Spring MVC, CDI→Spring DI |
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Install (pip or pipx)
|
|
57
|
+
pip install legacy-migration-toolkit
|
|
58
|
+
# or
|
|
59
|
+
pipx install legacy-migration-toolkit
|
|
60
|
+
|
|
61
|
+
# No external dependencies needed — pure Python 3.8+ standard library
|
|
62
|
+
|
|
63
|
+
# Run the demo (creates sample legacy + migrated files with intentional code losses)
|
|
64
|
+
legacy-migration --demo
|
|
65
|
+
|
|
66
|
+
# Migrate your actual legacy codebase (interactive, class-by-class)
|
|
67
|
+
legacy-migration --legacy /path/to/legacy/src/main/java --migrated /path/to/new/src/main/java
|
|
68
|
+
|
|
69
|
+
# Fix detected losses when you're ready
|
|
70
|
+
python3 fix_issues.py
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## The 5-Phase Workflow
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
77
|
+
│ │
|
|
78
|
+
│ Phase 1: ANALYZE │
|
|
79
|
+
│ ├─ Parse all legacy .java files │
|
|
80
|
+
│ ├─ Extract: classes, methods, fields, annotations, imports │
|
|
81
|
+
│ ├─ Classify: EJB, JPA, JAX-RS, CDI, Servlet, POJO │
|
|
82
|
+
│ └─ Fingerprint: SHA-256 hash of each method body │
|
|
83
|
+
│ │
|
|
84
|
+
│ Phase 2: PLAN │
|
|
85
|
+
│ ├─ Prioritize: Entities → Interfaces → Services → REST → MDB │
|
|
86
|
+
│ ├─ Dependency analysis: which classes are most depended-on │
|
|
87
|
+
│ └─ Copilot strategy: CHUNKED vs HYBRID vs FULL CLASS │
|
|
88
|
+
│ │
|
|
89
|
+
│ Phase 3: GENERATE (Copilot Prompts) │
|
|
90
|
+
│ ├─ Class scaffold prompt (structure + injections) │
|
|
91
|
+
│ ├─ Per-method prompts (one method at a time!) │
|
|
92
|
+
│ ├─ Test generation prompts │
|
|
93
|
+
│ └─ Each prompt includes verification checklist │
|
|
94
|
+
│ │
|
|
95
|
+
│ ══════ Developer uses Copilot with generated prompts ══════ │
|
|
96
|
+
│ │
|
|
97
|
+
│ Phase 4: DETECT (Code Loss Detection) │
|
|
98
|
+
│ ├─ Missing classes, methods, fields │
|
|
99
|
+
│ ├─ Signature changes (params, return types) │
|
|
100
|
+
│ ├─ Body changes (>50% size diff = suspicious) │
|
|
101
|
+
│ ├─ Annotation drift (EJB→Spring mapping validation) │
|
|
102
|
+
│ └─ Severity: CRITICAL / HIGH / MEDIUM / LOW │
|
|
103
|
+
│ │
|
|
104
|
+
│ Phase 5: REPAIR (Fix Prompts) │
|
|
105
|
+
│ ├─ Targeted Copilot prompts for each detected loss │
|
|
106
|
+
│ └─ Repeat Phase 4→5 until zero critical/high issues │
|
|
107
|
+
│ │
|
|
108
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## How to Use with GitHub Copilot
|
|
112
|
+
|
|
113
|
+
### Strategy: Chunk, Don't Dump
|
|
114
|
+
|
|
115
|
+
The #1 mistake developers make is pasting an entire 500-line EJB into Copilot and asking "convert this to Spring Boot." Copilot will:
|
|
116
|
+
- Lose context halfway through
|
|
117
|
+
- Skip methods it considers "obvious"
|
|
118
|
+
- Drop error handling, null checks, and edge cases
|
|
119
|
+
- Miss injection points
|
|
120
|
+
|
|
121
|
+
**Instead, this toolkit generates focused, single-concern prompts.**
|
|
122
|
+
|
|
123
|
+
### Recommended Copilot Workflow
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
1. Run: python3 run_migration.py analyze --legacy ./src/main/java
|
|
127
|
+
2. Open: reports/03_copilot_prompts/{ClassName}/
|
|
128
|
+
3. For each class:
|
|
129
|
+
a. Open 01_scaffold_{ClassName}.txt → paste into Copilot Chat
|
|
130
|
+
b. Copilot generates the class skeleton
|
|
131
|
+
c. Open 02_method_{ClassName}_{methodName}_*.txt → paste one at a time
|
|
132
|
+
d. Copilot fills in each method with full context
|
|
133
|
+
e. Check off the verification checklist at the bottom of each prompt
|
|
134
|
+
4. Run: python3 run_migration.py detect --legacy ./old --migrated ./new
|
|
135
|
+
5. Open: reports/04_code_loss_report.md → review all findings
|
|
136
|
+
6. Start Copilot/Cursor with `reports/AGENT_MIGRATION_INSTRUCTIONS.md`, then use prompts in `reports/03_copilot_prompts/`.
|
|
137
|
+
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.
|
|
138
|
+
8. Repeat steps 4-7 until the report shows zero CRITICAL/HIGH issues
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Class Mapping Overrides
|
|
142
|
+
|
|
143
|
+
If you renamed classes during migration, provide a mapping file:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"com.example.legacy.OrderBean": "com.example.service.OrderService",
|
|
148
|
+
"com.example.legacy.OrderDAOImpl": "com.example.repository.OrderRepository"
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
python3 run_migration.py detect \
|
|
154
|
+
--legacy ./old/src --migrated ./new/src \
|
|
155
|
+
--class-map ./class_mapping.json
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## What Gets Detected
|
|
159
|
+
|
|
160
|
+
| Detection Type | Severity | Example |
|
|
161
|
+
|---------------|----------|---------|
|
|
162
|
+
| Missing Class | CRITICAL | `OrderService` has no equivalent in new code |
|
|
163
|
+
| Missing Method | CRITICAL | `cancelOrder()` entirely missing |
|
|
164
|
+
| Signature Change | HIGH | `createOrder(Request)` → `createOrder(Customer, List)` |
|
|
165
|
+
| Body Change (>50% diff) | HIGH | Method went from 40 lines to 15 lines |
|
|
166
|
+
| Missing Injection | HIGH | `@EJB InventoryService` not wired in new code |
|
|
167
|
+
| Annotation Drift | MEDIUM | `@Stateless` not mapped to `@Service` |
|
|
168
|
+
| Interface Dropped | MEDIUM | `implements Serializable` removed |
|
|
169
|
+
| Body Change (minor) | LOW | Small refactoring detected |
|
|
170
|
+
|
|
171
|
+
## Project Structure
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
legacy-migration-toolkit/
|
|
175
|
+
├── run_migration.py # CLI entry point
|
|
176
|
+
├── requirements.txt # No external deps needed
|
|
177
|
+
├── src/
|
|
178
|
+
│ ├── analyzers/
|
|
179
|
+
│ │ └── java_parser.py # Parses legacy Java files
|
|
180
|
+
│ ├── detectors/
|
|
181
|
+
│ │ └── code_loss_detector.py # Compares legacy vs migrated
|
|
182
|
+
│ ├── generators/
|
|
183
|
+
│ │ └── copilot_prompt_generator.py # Creates Copilot prompts
|
|
184
|
+
│ └── orchestrator/
|
|
185
|
+
│ └── migration_workflow.py # Ties everything together
|
|
186
|
+
├── examples/
|
|
187
|
+
│ ├── legacy_code/ # Sample JBoss EJB code
|
|
188
|
+
│ └── migrated_code/ # Sample Spring Boot code (with losses)
|
|
189
|
+
├── reports/ # Generated reports land here
|
|
190
|
+
└── templates/ # Prompt templates
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Supported Migrations
|
|
194
|
+
|
|
195
|
+
| From (Legacy) | To (Target) |
|
|
196
|
+
|---------------|-------------|
|
|
197
|
+
| EJB @Stateless | Spring @Service |
|
|
198
|
+
| EJB @Stateful | Spring @Service + @SessionScope |
|
|
199
|
+
| EJB @MessageDriven | Spring @JmsListener |
|
|
200
|
+
| JAX-RS @Path | Spring @RestController |
|
|
201
|
+
| JPA @Entity | JPA @Entity (javax→jakarta) |
|
|
202
|
+
| CDI @Inject | Spring @Autowired / Constructor Injection |
|
|
203
|
+
| Servlet | Spring @Controller |
|
|
204
|
+
|
|
205
|
+
Target frameworks: **Spring Boot** (default), **Quarkus**, **Micronaut**
|
|
206
|
+
|
|
207
|
+
## Additional Suggestions
|
|
208
|
+
|
|
209
|
+
Beyond this toolkit, consider these approaches for large-scale migrations:
|
|
210
|
+
|
|
211
|
+
1. **Strangler Fig Pattern**: Don't migrate everything at once. Wrap legacy services behind a facade and replace them one by one.
|
|
212
|
+
|
|
213
|
+
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.
|
|
214
|
+
|
|
215
|
+
3. **Copilot Custom Instructions**: In your GitHub Copilot settings, add a custom instruction like:
|
|
216
|
+
> "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."
|
|
217
|
+
|
|
218
|
+
4. **Batch Processing with Copilot CLI**: For teams, use `gh copilot` CLI to script prompt execution across multiple files.
|
|
219
|
+
|
|
220
|
+
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.
|
|
221
|
+
|
|
222
|
+
## Packaging (pip)
|
|
223
|
+
|
|
224
|
+
### Local install (dev)
|
|
225
|
+
```bash
|
|
226
|
+
# In repo root
|
|
227
|
+
python3 -m venv .venv
|
|
228
|
+
.venv/bin/python setup.py develop
|
|
229
|
+
legacy-migration --help
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Build and publish to PyPI
|
|
233
|
+
```bash
|
|
234
|
+
python3 -m pip install build twine
|
|
235
|
+
python3 -m build
|
|
236
|
+
twine upload dist/*
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Update the package
|
|
240
|
+
1. Bump the version in `pyproject.toml` and `setup.py`.
|
|
241
|
+
2. Rebuild and republish (`python3 -m build`, then `twine upload dist/*`).
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Legacy Migration Toolkit
|
|
2
|
+
|
|
3
|
+
**Python-based automation for Java/JBoss to Microservices migration with GitHub Copilot.**
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
Solves the most redundant problem in enterprise Java: migrating complex legacy EJB/JBoss code to Spring Boot/Quarkus microservices **without losing business logic**.
|
|
8
|
+
|
|
9
|
+
## The Problem
|
|
10
|
+
|
|
11
|
+
| Challenge | How This Toolkit Solves It |
|
|
12
|
+
|-----------|---------------------------|
|
|
13
|
+
| Copilot loses context on large legacy files | **Chunked prompts** — one method per prompt, not entire classes |
|
|
14
|
+
| Code loss during migration (methods, logic, validations) | **Automated code loss detection** — compares legacy vs migrated code |
|
|
15
|
+
| Tedious manual file-by-file comparison | **Hash-based fingerprinting** — detects body changes, missing methods, annotation drift |
|
|
16
|
+
| No systematic migration approach | **5-phase workflow** — analyze, plan, generate, detect, repair |
|
|
17
|
+
| JEE annotations not properly translated | **Annotation mapping** — EJB→Spring, JAX-RS→Spring MVC, CDI→Spring DI |
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Install (pip or pipx)
|
|
23
|
+
pip install legacy-migration-toolkit
|
|
24
|
+
# or
|
|
25
|
+
pipx install legacy-migration-toolkit
|
|
26
|
+
|
|
27
|
+
# No external dependencies needed — pure Python 3.8+ standard library
|
|
28
|
+
|
|
29
|
+
# Run the demo (creates sample legacy + migrated files with intentional code losses)
|
|
30
|
+
legacy-migration --demo
|
|
31
|
+
|
|
32
|
+
# Migrate your actual legacy codebase (interactive, class-by-class)
|
|
33
|
+
legacy-migration --legacy /path/to/legacy/src/main/java --migrated /path/to/new/src/main/java
|
|
34
|
+
|
|
35
|
+
# Fix detected losses when you're ready
|
|
36
|
+
python3 fix_issues.py
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## The 5-Phase Workflow
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
43
|
+
│ │
|
|
44
|
+
│ Phase 1: ANALYZE │
|
|
45
|
+
│ ├─ Parse all legacy .java files │
|
|
46
|
+
│ ├─ Extract: classes, methods, fields, annotations, imports │
|
|
47
|
+
│ ├─ Classify: EJB, JPA, JAX-RS, CDI, Servlet, POJO │
|
|
48
|
+
│ └─ Fingerprint: SHA-256 hash of each method body │
|
|
49
|
+
│ │
|
|
50
|
+
│ Phase 2: PLAN │
|
|
51
|
+
│ ├─ Prioritize: Entities → Interfaces → Services → REST → MDB │
|
|
52
|
+
│ ├─ Dependency analysis: which classes are most depended-on │
|
|
53
|
+
│ └─ Copilot strategy: CHUNKED vs HYBRID vs FULL CLASS │
|
|
54
|
+
│ │
|
|
55
|
+
│ Phase 3: GENERATE (Copilot Prompts) │
|
|
56
|
+
│ ├─ Class scaffold prompt (structure + injections) │
|
|
57
|
+
│ ├─ Per-method prompts (one method at a time!) │
|
|
58
|
+
│ ├─ Test generation prompts │
|
|
59
|
+
│ └─ Each prompt includes verification checklist │
|
|
60
|
+
│ │
|
|
61
|
+
│ ══════ Developer uses Copilot with generated prompts ══════ │
|
|
62
|
+
│ │
|
|
63
|
+
│ Phase 4: DETECT (Code Loss Detection) │
|
|
64
|
+
│ ├─ Missing classes, methods, fields │
|
|
65
|
+
│ ├─ Signature changes (params, return types) │
|
|
66
|
+
│ ├─ Body changes (>50% size diff = suspicious) │
|
|
67
|
+
│ ├─ Annotation drift (EJB→Spring mapping validation) │
|
|
68
|
+
│ └─ Severity: CRITICAL / HIGH / MEDIUM / LOW │
|
|
69
|
+
│ │
|
|
70
|
+
│ Phase 5: REPAIR (Fix Prompts) │
|
|
71
|
+
│ ├─ Targeted Copilot prompts for each detected loss │
|
|
72
|
+
│ └─ Repeat Phase 4→5 until zero critical/high issues │
|
|
73
|
+
│ │
|
|
74
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## How to Use with GitHub Copilot
|
|
78
|
+
|
|
79
|
+
### Strategy: Chunk, Don't Dump
|
|
80
|
+
|
|
81
|
+
The #1 mistake developers make is pasting an entire 500-line EJB into Copilot and asking "convert this to Spring Boot." Copilot will:
|
|
82
|
+
- Lose context halfway through
|
|
83
|
+
- Skip methods it considers "obvious"
|
|
84
|
+
- Drop error handling, null checks, and edge cases
|
|
85
|
+
- Miss injection points
|
|
86
|
+
|
|
87
|
+
**Instead, this toolkit generates focused, single-concern prompts.**
|
|
88
|
+
|
|
89
|
+
### Recommended Copilot Workflow
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
1. Run: python3 run_migration.py analyze --legacy ./src/main/java
|
|
93
|
+
2. Open: reports/03_copilot_prompts/{ClassName}/
|
|
94
|
+
3. For each class:
|
|
95
|
+
a. Open 01_scaffold_{ClassName}.txt → paste into Copilot Chat
|
|
96
|
+
b. Copilot generates the class skeleton
|
|
97
|
+
c. Open 02_method_{ClassName}_{methodName}_*.txt → paste one at a time
|
|
98
|
+
d. Copilot fills in each method with full context
|
|
99
|
+
e. Check off the verification checklist at the bottom of each prompt
|
|
100
|
+
4. Run: python3 run_migration.py detect --legacy ./old --migrated ./new
|
|
101
|
+
5. Open: reports/04_code_loss_report.md → review all findings
|
|
102
|
+
6. Start Copilot/Cursor with `reports/AGENT_MIGRATION_INSTRUCTIONS.md`, then use prompts in `reports/03_copilot_prompts/`.
|
|
103
|
+
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.
|
|
104
|
+
8. Repeat steps 4-7 until the report shows zero CRITICAL/HIGH issues
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Class Mapping Overrides
|
|
108
|
+
|
|
109
|
+
If you renamed classes during migration, provide a mapping file:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"com.example.legacy.OrderBean": "com.example.service.OrderService",
|
|
114
|
+
"com.example.legacy.OrderDAOImpl": "com.example.repository.OrderRepository"
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
python3 run_migration.py detect \
|
|
120
|
+
--legacy ./old/src --migrated ./new/src \
|
|
121
|
+
--class-map ./class_mapping.json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## What Gets Detected
|
|
125
|
+
|
|
126
|
+
| Detection Type | Severity | Example |
|
|
127
|
+
|---------------|----------|---------|
|
|
128
|
+
| Missing Class | CRITICAL | `OrderService` has no equivalent in new code |
|
|
129
|
+
| Missing Method | CRITICAL | `cancelOrder()` entirely missing |
|
|
130
|
+
| Signature Change | HIGH | `createOrder(Request)` → `createOrder(Customer, List)` |
|
|
131
|
+
| Body Change (>50% diff) | HIGH | Method went from 40 lines to 15 lines |
|
|
132
|
+
| Missing Injection | HIGH | `@EJB InventoryService` not wired in new code |
|
|
133
|
+
| Annotation Drift | MEDIUM | `@Stateless` not mapped to `@Service` |
|
|
134
|
+
| Interface Dropped | MEDIUM | `implements Serializable` removed |
|
|
135
|
+
| Body Change (minor) | LOW | Small refactoring detected |
|
|
136
|
+
|
|
137
|
+
## Project Structure
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
legacy-migration-toolkit/
|
|
141
|
+
├── run_migration.py # CLI entry point
|
|
142
|
+
├── requirements.txt # No external deps needed
|
|
143
|
+
├── src/
|
|
144
|
+
│ ├── analyzers/
|
|
145
|
+
│ │ └── java_parser.py # Parses legacy Java files
|
|
146
|
+
│ ├── detectors/
|
|
147
|
+
│ │ └── code_loss_detector.py # Compares legacy vs migrated
|
|
148
|
+
│ ├── generators/
|
|
149
|
+
│ │ └── copilot_prompt_generator.py # Creates Copilot prompts
|
|
150
|
+
│ └── orchestrator/
|
|
151
|
+
│ └── migration_workflow.py # Ties everything together
|
|
152
|
+
├── examples/
|
|
153
|
+
│ ├── legacy_code/ # Sample JBoss EJB code
|
|
154
|
+
│ └── migrated_code/ # Sample Spring Boot code (with losses)
|
|
155
|
+
├── reports/ # Generated reports land here
|
|
156
|
+
└── templates/ # Prompt templates
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Supported Migrations
|
|
160
|
+
|
|
161
|
+
| From (Legacy) | To (Target) |
|
|
162
|
+
|---------------|-------------|
|
|
163
|
+
| EJB @Stateless | Spring @Service |
|
|
164
|
+
| EJB @Stateful | Spring @Service + @SessionScope |
|
|
165
|
+
| EJB @MessageDriven | Spring @JmsListener |
|
|
166
|
+
| JAX-RS @Path | Spring @RestController |
|
|
167
|
+
| JPA @Entity | JPA @Entity (javax→jakarta) |
|
|
168
|
+
| CDI @Inject | Spring @Autowired / Constructor Injection |
|
|
169
|
+
| Servlet | Spring @Controller |
|
|
170
|
+
|
|
171
|
+
Target frameworks: **Spring Boot** (default), **Quarkus**, **Micronaut**
|
|
172
|
+
|
|
173
|
+
## Additional Suggestions
|
|
174
|
+
|
|
175
|
+
Beyond this toolkit, consider these approaches for large-scale migrations:
|
|
176
|
+
|
|
177
|
+
1. **Strangler Fig Pattern**: Don't migrate everything at once. Wrap legacy services behind a facade and replace them one by one.
|
|
178
|
+
|
|
179
|
+
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.
|
|
180
|
+
|
|
181
|
+
3. **Copilot Custom Instructions**: In your GitHub Copilot settings, add a custom instruction like:
|
|
182
|
+
> "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."
|
|
183
|
+
|
|
184
|
+
4. **Batch Processing with Copilot CLI**: For teams, use `gh copilot` CLI to script prompt execution across multiple files.
|
|
185
|
+
|
|
186
|
+
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.
|
|
187
|
+
|
|
188
|
+
## Packaging (pip)
|
|
189
|
+
|
|
190
|
+
### Local install (dev)
|
|
191
|
+
```bash
|
|
192
|
+
# In repo root
|
|
193
|
+
python3 -m venv .venv
|
|
194
|
+
.venv/bin/python setup.py develop
|
|
195
|
+
legacy-migration --help
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Build and publish to PyPI
|
|
199
|
+
```bash
|
|
200
|
+
python3 -m pip install build twine
|
|
201
|
+
python3 -m build
|
|
202
|
+
twine upload dist/*
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Update the package
|
|
206
|
+
1. Bump the version in `pyproject.toml` and `setup.py`.
|
|
207
|
+
2. Rebuild and republish (`python3 -m build`, then `twine upload dist/*`).
|