An AI-powered tool for migrating Java/Maven projects, available as both a Python application and a VS Code extension.
- Automated Java/Maven project migration
- Spring Boot version upgrades
- Dependency analysis and updates
- Interactive migration process with user confirmation
- Detailed logging and HTML reports
- AI-powered reasoning for migration decisions
- Real-time progress tracking
- Comprehensive error handling
- Python 3.8 or higher
- Java Development Kit (JDK) 8 or higher
- Maven 3.6 or higher
- Access to MCP servers (file explorer, file parser, maven)
- Gemini API key
- Visual Studio Code 1.60 or higher
- Java Extension Pack for VS Code
- Java Development Kit (JDK) 8 or higher
- Maven 3.6 or higher
- Access to MCP servers (file explorer, file parser, maven)
- Gemini API key
The Java Migration Assistant uses Google's Gemini LLM to provide intelligent migration strategies and reasoning. The LLM is used in both Python and VS Code extension modes for:
-
Migration Analysis
- Project structure analysis
- Dependency compatibility assessment
- Migration path determination
- Risk analysis
-
Reasoning Generation
- Step-by-step migration reasoning
- Potential issues identification
- Best practices recommendations
- Alternative approaches
-
Error Analysis
- Compilation error analysis
- Test failure interpretation
- Migration failure diagnosis
- Solution suggestions
Configure the LLM in config.py:
# Gemini API Configuration
GEMINI_API_KEY = 'your-api-key-here'
# LLM Model Settings
LLM_SETTINGS = {
'model': 'gemini-pro',
'temperature': 0.7,
'max_tokens': 2048,
'top_p': 0.95,
'frequency_penalty': 0.0,
'presence_penalty': 0.0
}
# Custom Prompts (optional)
CUSTOM_PROMPTS = {
'analysis': "Analyze the following Java project for migration...",
'reasoning': "Provide reasoning for the following migration step...",
'error': "Analyze the following error and suggest solutions..."
}Configure the LLM through VS Code settings:
{
"javaMigrationAssistant.geminiApiKey": "your-api-key-here",
"javaMigrationAssistant.llmSettings": {
"model": "gemini-pro",
"temperature": 0.7,
"maxTokens": 2048,
"topP": 0.95,
"frequencyPenalty": 0.0,
"presencePenalty": 0.0
},
"javaMigrationAssistant.customPrompts": {
"analysis": "Analyze the following Java project for migration...",
"reasoning": "Provide reasoning for the following migration step...",
"error": "Analyze the following error and suggest solutions..."
}
}-
Temperature
- Lower values (0.1-0.3): More focused, deterministic responses
- Higher values (0.7-0.9): More creative, diverse suggestions
- Default: 0.7 (balanced between focus and creativity)
-
Max Tokens
- Controls response length
- Default: 2048 (sufficient for detailed analysis)
- Increase for more detailed responses
- Decrease for more concise outputs
-
Custom Prompts
- Modify the prompts to focus on specific aspects
- Add domain-specific context
- Include project-specific requirements
- Customize error analysis approach
-
Response Format
- Structured JSON output for consistent parsing
- Markdown formatting for better readability
- HTML integration for reports
- Custom formatting for specific needs
- Project Analysis
# Python Mode
reasoning = await orchestrator.get_llm_reasoning({
"step": "Project Analysis",
"project_structure": project_structure,
"dependencies": dependencies
})- Migration Strategy
# Python Mode
strategy = await orchestrator.get_migration_strategy({
"current_version": "1.5.22",
"target_version": "2.7.0",
"dependencies": dependencies,
"project_type": "spring-boot"
})- Error Analysis
# Python Mode
error_analysis = await orchestrator.get_llm_reasoning({
"step": "Error Analysis",
"error": compilation_error,
"context": {
"step": "Compilation",
"file": "MainApplication.java",
"line": 42
}
})-
API Key Management
- Store API keys securely
- Use environment variables when possible
- Rotate keys regularly
- Monitor API usage
-
Prompt Engineering
- Be specific in prompts
- Include relevant context
- Use clear instructions
- Test and refine prompts
-
Error Handling
- Implement fallback strategies
- Log LLM responses
- Handle API limits
- Provide user feedback
-
Performance Optimization
- Cache common responses
- Batch similar requests
- Optimize token usage
- Monitor response times
-
Clone the repository:
git clone <repository-url> cd java-migration-assistant
-
Create and activate a virtual environment:
python -m venv venv # On Windows .\venv\Scripts\activate # On Unix or MacOS source venv/bin/activate
-
Install dependencies:
pip install -r requirements.txt
-
Configure the MCP servers in
config.py:MCP_SERVERS = { 'file_explorer': {'host': 'localhost', 'port': 8001}, 'file_parser': {'host': 'localhost', 'port': 8002}, 'maven': {'host': 'localhost', 'port': 8003} }
-
Set up your Gemini API key in
config.py:GEMINI_API_KEY = 'your-api-key-here'
-
Install the extension from VS Code Marketplace:
- Open VS Code
- Go to Extensions (Ctrl+Shift+X)
- Search for "Java Migration Assistant"
- Click Install
-
Configure the extension:
- Open VS Code Settings (Ctrl+,)
- Search for "Java Migration Assistant"
- Configure the following settings:
{ "javaMigrationAssistant.mcpServers": { "fileExplorer": { "host": "localhost", "port": 8001 }, "fileParser": { "host": "localhost", "port": 8002 }, "maven": { "host": "localhost", "port": 8003 } }, "javaMigrationAssistant.geminiApiKey": "your-api-key-here" }
-
Activate your virtual environment if not already activated:
# On Windows .\venv\Scripts\activate # On Unix or MacOS source venv/bin/activate
-
Run the migration assistant:
python main.py
-
When prompted, enter the path to your Java/Maven project.
-
Follow the interactive prompts to complete the migration.
-
Open your Java/Maven project in VS Code.
-
Start the migration:
- Press
Ctrl+Shift+P(orCmd+Shift+Pon Mac) - Type "Start Java Migration"
- Press Enter
- Press
-
The migration process will begin, and you can:
- View progress in the Migration Steps view
- See detailed information in the Migration Report view
- Interact with confirmation dialogs
- View the final report in a new editor
The migration process includes the following steps:
-
Project Exploration
- Analyzes project structure
- Identifies key files and dependencies
-
POM Analysis
- Parses pom.xml
- Identifies dependencies and properties
-
Spring Boot Verification
- Checks if project uses Spring Boot
- Determines current version
-
Initial Compilation
- Verifies project compiles successfully
- Identifies any compilation issues
-
Test Execution
- Runs project tests
- Ensures test coverage
-
Migration Path Determination
- Analyzes current state
- Determines optimal migration path
-
Migration Execution
- Updates dependencies
- Modifies code as needed
- Applies migration recipes
-
Post-migration Verification
- Recompiles project
- Runs tests again
- Verifies changes
-
Report Generation
- Creates detailed HTML report
- Includes all steps and changes
google.generativeai==0.1.0
httpx==0.24.0
{
"dependencies": {
"google.generativeai": "^0.1.0",
"httpx": "^0.24.0"
}
}- Operating System: Windows 10/11, macOS 10.15+, or Linux
- Memory: 4GB RAM minimum (8GB recommended)
- Disk Space: 500MB minimum
- Internet Connection: Required for API access
- File Explorer Server: Port 8001
- File Parser Server: Port 8002
- Maven Server: Port 8003
-
MCP Server Connection
- Ensure all MCP servers are running
- Verify correct host and port configurations
- Check firewall settings
-
API Key Issues
- Verify Gemini API key is correctly set
- Ensure API key has sufficient permissions
- Check API quota limits
-
Java/Maven Issues
- Verify Java and Maven installations
- Check JAVA_HOME environment variable
- Ensure Maven is in system PATH
- Check the logs in the
logsdirectory - Review the HTML report for detailed information
- Submit issues on the GitHub repository
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Here are specific examples of LLM prompts used in different migration scenarios:
- Spring Boot Version Migration
SPRING_BOOT_MIGRATION_PROMPT = """
Analyze the following Spring Boot project for migration from version {current_version} to {target_version}:
Project Structure:
{project_structure}
Dependencies:
{dependencies}
Please provide:
1. Breaking changes between versions
2. Required dependency updates
3. Code modifications needed
4. Potential risks and mitigation strategies
5. Step-by-step migration plan
Format the response as JSON with the following structure:
{
"breaking_changes": [],
"dependency_updates": [],
"code_modifications": [],
"risks": [],
"migration_steps": []
}
"""- Java Version Upgrade
JAVA_VERSION_UPGRADE_PROMPT = """
Analyze the Java project for migration from Java {current_version} to Java {target_version}:
Source Code:
{source_code}
Build Configuration:
{build_config}
Please analyze:
1. Language feature compatibility
2. API changes and deprecations
3. Performance implications
4. Required code modifications
5. Testing requirements
Provide a detailed analysis with specific code examples and recommendations.
"""- Dependency Conflict Resolution
DEPENDENCY_CONFLICT_PROMPT = """
Analyze the following dependency conflicts in the Maven project:
Conflicts:
{conflicts}
Current Dependencies:
{dependencies}
Please:
1. Identify the root cause of conflicts
2. Suggest compatible versions
3. Propose alternative dependencies if needed
4. Assess impact on existing functionality
5. Provide a resolution strategy
Include specific version recommendations and explain the reasoning.
"""- Migration Error Analysis
MIGRATION_ERROR_PROMPT = """
Analyze the following migration error:
Error Message:
{error_message}
Context:
- Step: {step_name}
- File: {file_name}
- Line: {line_number}
- Previous Steps: {previous_steps}
Please provide:
1. Error root cause analysis
2. Impact assessment
3. Possible solutions with pros/cons
4. Recommended fix
5. Prevention strategies for future
Format the response with clear sections and code examples where relevant.
"""- Test Compatibility Check
TEST_COMPATIBILITY_PROMPT = """
Analyze test compatibility for the following migration:
Current Tests:
{test_files}
Migration Changes:
{migration_changes}
Please evaluate:
1. Test framework compatibility
2. Required test modifications
3. New test cases needed
4. Test coverage gaps
5. Migration testing strategy
Provide specific recommendations for each test file and testing approach.
"""- Performance Impact Analysis
PERFORMANCE_ANALYSIS_PROMPT = """
Analyze potential performance impacts of the following migration:
Current Metrics:
{current_metrics}
Proposed Changes:
{migration_changes}
Please assess:
1. Expected performance changes
2. Bottleneck identification
3. Optimization opportunities
4. Monitoring requirements
5. Performance testing strategy
Include specific metrics to track and benchmark recommendations.
"""- Security Assessment
SECURITY_ASSESSMENT_PROMPT = """
Assess security implications of the following migration:
Current Security:
{security_config}
Migration Changes:
{migration_changes}
Please evaluate:
1. Security vulnerability risks
2. Dependency security updates
3. Required security configurations
4. Best practices compliance
5. Security testing requirements
Provide a comprehensive security analysis with specific recommendations.
"""- Custom Migration Recipe
CUSTOM_RECIPE_PROMPT = """
Generate a custom migration recipe for the following scenario:
Project Type: {project_type}
Current State: {current_state}
Target State: {target_state}
Special Requirements: {requirements}
Please create:
1. Step-by-step migration instructions
2. Required code transformations
3. Validation checks
4. Rollback procedures
5. Success criteria
Format as a structured recipe with clear steps and code examples.
"""These prompts can be customized based on your specific needs by:
- Adding project-specific context
- Including domain-specific requirements
- Modifying the response format
- Adding additional analysis criteria
- Incorporating custom validation rules
Example usage in code:
# Python Mode
async def analyze_migration_path(self, project_path: str, pom_analysis: Dict) -> Tuple[str, Dict]:
prompt = SPRING_BOOT_MIGRATION_PROMPT.format(
current_version=pom_analysis.get("spring_boot_version", "unknown"),
target_version="2.7.0",
project_structure=json.dumps(self.project_structure, indent=2),
dependencies=json.dumps(pom_analysis.get("dependencies", []), indent=2)
)
response = await self.get_llm_response(prompt)
analysis = json.loads(response)
return analysis.get("migration_type"), analysis.get("migration_target")The Java Migration Assistant uses advanced LLM capabilities to learn from previous results and engage in multi-turn conversations to refine migration strategies.
- Dependency Resolution Learning
# First attempt at dependency resolution
async def resolve_dependency_conflicts(self, conflicts: List[Dict]) -> Dict:
prompt = DEPENDENCY_CONFLICT_PROMPT.format(
conflicts=json.dumps(conflicts, indent=2),
dependencies=json.dumps(self.current_dependencies, indent=2)
)
response = await self.get_llm_response(prompt)
resolution = json.loads(response)
# Store the resolution attempt for learning
self.resolution_history.append({
"conflicts": conflicts,
"resolution": resolution,
"success": False # Will be updated after verification
})
return resolution
# Second attempt with learning from previous failures
async def resolve_dependency_conflicts_with_learning(self, conflicts: List[Dict]) -> Dict:
# Include previous resolution attempts in the prompt
previous_attempts = self.resolution_history[-3:] if self.resolution_history else []
prompt = DEPENDENCY_CONFLICT_WITH_HISTORY_PROMPT.format(
conflicts=json.dumps(conflicts, indent=2),
dependencies=json.dumps(self.current_dependencies, indent=2),
previous_attempts=json.dumps(previous_attempts, indent=2)
)
response = await self.get_llm_response(prompt)
resolution = json.loads(response)
# Store the new resolution attempt
self.resolution_history.append({
"conflicts": conflicts,
"resolution": resolution,
"success": False # Will be updated after verification
})
return resolution- Migration Path Refinement
# Refine migration path based on previous steps
async def refine_migration_path(self, current_step: str, results: Dict) -> Dict:
# Include previous steps and their results
previous_steps = self.migration_history[-5:] if self.migration_history else []
prompt = MIGRATION_PATH_REFINEMENT_PROMPT.format(
current_step=current_step,
current_results=json.dumps(results, indent=2),
previous_steps=json.dumps(previous_steps, indent=2),
project_context=json.dumps(self.project_context, indent=2)
)
response = await self.get_llm_response(prompt)
refined_path = json.loads(response)
# Update migration history
self.migration_history.append({
"step": current_step,
"results": results,
"refined_path": refined_path
})
return refined_path- Error Recovery Learning
# Learn from error recovery attempts
async def recover_from_error(self, error: Dict, context: Dict) -> Dict:
# Include previous error recovery attempts
previous_recoveries = self.error_recovery_history[-3:] if self.error_recovery_history else []
prompt = ERROR_RECOVERY_WITH_HISTORY_PROMPT.format(
error=json.dumps(error, indent=2),
context=json.dumps(context, indent=2),
previous_recoveries=json.dumps(previous_recoveries, indent=2)
)
response = await self.get_llm_response(prompt)
recovery_plan = json.loads(response)
# Store the recovery attempt
self.error_recovery_history.append({
"error": error,
"context": context,
"recovery_plan": recovery_plan,
"success": False # Will be updated after verification
})
return recovery_plan- Interactive Migration Planning
# Multi-turn migration planning conversation
async def interactive_migration_planning(self, project_path: str) -> Dict:
# Initial analysis
initial_analysis = await self.analyze_project(project_path)
# Start conversation with LLM
conversation = []
conversation.append({
"role": "system",
"content": "You are a Java migration expert. Help plan the migration of this project."
})
conversation.append({
"role": "user",
"content": f"Analyze this project and suggest a migration plan: {json.dumps(initial_analysis, indent=2)}"
})
# Get initial response
response = await self.get_llm_conversation_response(conversation)
conversation.append({
"role": "assistant",
"content": response
})
# Continue conversation with user input
while True:
# Get user feedback
user_feedback = await self.prompt_user(
"Do you want to modify the migration plan? (yes/no)",
["Yes", "No"]
)
if user_feedback.lower() == "no":
break
# Get specific modifications
modification_request = await self.prompt_user(
"What aspects of the plan would you like to modify?",
["Dependencies", "Migration Steps", "Timeline", "Other"]
)
# Add user request to conversation
conversation.append({
"role": "user",
"content": f"Please modify the {modification_request} aspect of the migration plan."
})
# Get updated plan
response = await self.get_llm_conversation_response(conversation)
conversation.append({
"role": "assistant",
"content": response
})
# Finalize the plan
final_plan = json.loads(conversation[-1]["content"])
return final_plan- Iterative Problem Solving
# Multi-turn problem solving for complex migration issues
async def solve_migration_problem(self, problem: Dict) -> Dict:
# Initialize conversation
conversation = []
conversation.append({
"role": "system",
"content": "You are a Java migration expert. Help solve this migration problem."
})
conversation.append({
"role": "user",
"content": f"Solve this migration problem: {json.dumps(problem, indent=2)}"
})
# Get initial solution
response = await self.get_llm_conversation_response(conversation)
conversation.append({
"role": "assistant",
"content": response
})
# Try the solution
solution = json.loads(response)
result = await self.apply_solution(solution)
# If solution failed, continue conversation
if not result["success"]:
conversation.append({
"role": "user",
"content": f"The solution failed with error: {json.dumps(result['error'], indent=2)}. Please provide an alternative solution."
})
# Get alternative solution
response = await self.get_llm_conversation_response(conversation)
conversation.append({
"role": "assistant",
"content": response
})
# Try the alternative solution
solution = json.loads(response)
result = await self.apply_solution(solution)
# Continue until success or max attempts
attempts = 1
while not result["success"] and attempts < 3:
conversation.append({
"role": "user",
"content": f"The solution still failed with error: {json.dumps(result['error'], indent=2)}. Please provide another alternative solution."
})
response = await self.get_llm_conversation_response(conversation)
conversation.append({
"role": "assistant",
"content": response
})
solution = json.loads(response)
result = await self.apply_solution(solution)
attempts += 1
return {
"solution": solution,
"success": result["success"],
"attempts": attempts,
"conversation": conversation
}- Adaptive Migration Strategy
# Adaptive migration strategy based on multi-turn feedback
async def adaptive_migration_strategy(self, project_path: str) -> Dict:
# Initial strategy
initial_strategy = await self.get_migration_strategy({
"project_path": project_path,
"current_state": await self.get_project_state(project_path)
})
# Start conversation
conversation = []
conversation.append({
"role": "system",
"content": "You are a Java migration expert. Help develop an adaptive migration strategy."
})
conversation.append({
"role": "user",
"content": f"Develop a migration strategy for this project: {json.dumps(initial_strategy, indent=2)}"
})
# Get initial strategy
response = await self.get_llm_conversation_response(conversation)
conversation.append({
"role": "assistant",
"content": response
})
# Execute first phase
strategy = json.loads(response)
phase_result = await self.execute_migration_phase(strategy["phases"][0])
# Adapt strategy based on results
conversation.append({
"role": "user",
"content": f"The first phase resulted in: {json.dumps(phase_result, indent=2)}. How should we adapt the strategy?"
})
# Get adapted strategy
response = await self.get_llm_conversation_response(conversation)
conversation.append({
"role": "assistant",
"content": response
})
# Continue adapting for each phase
adapted_strategy = json.loads(response)
for i in range(1, len(adapted_strategy["phases"])):
phase_result = await self.execute_migration_phase(adapted_strategy["phases"][i])
conversation.append({
"role": "user",
"content": f"Phase {i+1} resulted in: {json.dumps(phase_result, indent=2)}. How should we adapt the remaining strategy?"
})
response = await self.get_llm_conversation_response(conversation)
conversation.append({
"role": "assistant",
"content": response
})
adapted_strategy = json.loads(response)
return {
"final_strategy": adapted_strategy,
"conversation": conversation
}- Dependency Conflict with History Prompt
DEPENDENCY_CONFLICT_WITH_HISTORY_PROMPT = """
Analyze the following dependency conflicts in the Maven project, taking into account previous resolution attempts:
Conflicts:
{conflicts}
Current Dependencies:
{dependencies}
Previous Resolution Attempts:
{previous_attempts}
Please:
1. Review previous resolution attempts and their outcomes
2. Identify patterns in successful and failed resolutions
3. Suggest a new resolution strategy based on this learning
4. Explain how this strategy addresses previous failures
5. Provide a detailed implementation plan
Format the response as JSON with the following structure:
{
"analysis": {
"previous_successes": [],
"previous_failures": [],
"learned_patterns": []
},
"resolution_strategy": {
"approach": "",
"reasoning": "",
"steps": []
},
"implementation": {
"dependency_updates": [],
"version_changes": [],
"additional_changes": []
}
}
"""- Migration Path Refinement Prompt
MIGRATION_PATH_REFINEMENT_PROMPT = """
Refine the migration path based on previous steps and their results:
Current Step: {current_step}
Current Results: {current_results}
Previous Steps and Results:
{previous_steps}
Project Context:
{project_context}
Please:
1. Analyze the outcomes of previous steps
2. Identify any deviations from the expected path
3. Suggest adjustments to the remaining migration steps
4. Provide reasoning for the refinements
5. Update the migration timeline if needed
Format the response as JSON with the following structure:
{
"analysis": {
"previous_outcomes": [],
"deviations": [],
"success_patterns": []
},
"refined_path": {
"adjusted_steps": [],
"new_steps": [],
"removed_steps": [],
"timeline_adjustments": []
},
"reasoning": {
"adjustment_reasons": [],
"risk_assessment": [],
"mitigation_strategies": []
}
}
"""- Error Recovery with History Prompt
ERROR_RECOVERY_WITH_HISTORY_PROMPT = """
Develop a recovery plan for the following error, taking into account previous recovery attempts:
Error:
{error}
Context:
{context}
Previous Recovery Attempts:
{previous_recoveries}
Please:
1. Review previous recovery attempts and their outcomes
2. Identify why previous attempts may have failed
3. Propose a new recovery strategy based on this learning
4. Explain how this strategy addresses previous failures
5. Provide a detailed implementation plan
Format the response as JSON with the following structure:
{
"analysis": {
"error_root_cause": "",
"previous_attempt_analysis": [],
"failure_patterns": []
},
"recovery_strategy": {
"approach": "",
"reasoning": "",
"steps": []
},
"implementation": {
"code_changes": [],
"configuration_changes": [],
"verification_steps": []
}
}
"""These examples demonstrate how the Java Migration Assistant:
- Learns from previous migration attempts
- Adapts strategies based on outcomes
- Engages in multi-turn conversations to refine approaches
- Maintains conversation history for context
- Provides structured responses for consistent processing