{"id":36650174,"url":"https://github.com/snowdrop/migration-tool","last_synced_at":"2026-05-03T03:07:09.681Z","repository":{"id":316714168,"uuid":"1064548407","full_name":"snowdrop/migration-tool","owner":"snowdrop","description":"Project hosting the Quarkus scan, analyzer and migration tool to migrate spring to Quarkus","archived":false,"fork":false,"pushed_at":"2026-04-21T01:15:05.000Z","size":61238,"stargazers_count":1,"open_issues_count":31,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-21T03:03:06.835Z","etag":null,"topics":["ai","java","jdt-ls","migration","openrewrite","quarkus","recipes"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snowdrop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-26T07:40:03.000Z","updated_at":"2026-04-17T11:43:53.000Z","dependencies_parsed_at":"2026-03-01T03:07:14.240Z","dependency_job_id":"7745797e-5cbb-4299-b549-6030fa7435ab","html_url":"https://github.com/snowdrop/migration-tool","commit_stats":null,"previous_names":["snowdrop/migration-tool"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/snowdrop/migration-tool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowdrop%2Fmigration-tool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowdrop%2Fmigration-tool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowdrop%2Fmigration-tool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowdrop%2Fmigration-tool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snowdrop","download_url":"https://codeload.github.com/snowdrop/migration-tool/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowdrop%2Fmigration-tool/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32556771,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T00:31:16.350Z","status":"online","status_checked_at":"2026-05-03T02:00:09.297Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","java","jdt-ls","migration","openrewrite","quarkus","recipes"],"created_at":"2026-01-12T10:04:40.397Z","updated_at":"2026-05-03T03:07:09.640Z","avatar_url":"https://github.com/snowdrop.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub Actions :: Build status](\u003chttps://img.shields.io/github/actions/workflow/status/snowdrop/migration-tool/mvn-build.yml?branch=main\u0026logo=GitHub\u0026style=for-the-badge\u0026label=Compilation\u003e)](https://github.com/snowdrop/migration-tool/actions/workflows/mvn-build.yml)\n[![GitHub Actions :: e2e status](\u003chttps://img.shields.io/github/actions/workflow/status/snowdrop/migration-tool/e2e-tests.yml?branch=main\u0026logo=GitHub\u0026style=for-the-badge\u0026label=Integration-tests\u003e)](https://github.com/snowdrop/migration-tool/actions/workflows/e2e-tests.yml)\n[![License](https://img.shields.io/github/license/snowdrop/migration-tool?style=for-the-badge\u0026logo=apache)](https://www.apache.org/licenses/LICENSE-2.0)\n\n# Migration Tool project\n\nThis project and proof of concept show how to better handle the end-to-end migration of a Java application — for example, from Spring Boot to Quarkus — using new concepts that organize the process into ordered instructions managed by different providers. We’ve focused especially on making it easier for users to debug and test the transformation, particularly the matching conditions and resulting output.\n## Dictionary\n\n- **Rule**: A rule defines the information about what the tool will search within the code source of the project scanned like the instructions to be executed by a provider\n- **Provider**: A provider is a system able to execute the instructions defined part of a rule where the condition(s) matched. Different providers could be implemented such as: [Openrewrite recipe](https://docs.openrewrite.org/recipes), AI or user\n- **Analysis report**: The analysis report generated by a rule engine contains issues where each issue will tell to the tool or user what they should do, when it should be used and for which purpose.\n- **Migration plan**: A migration plan is an enhanced analysis report where the issue have been augmented with instructions that different providers could apply during the transformation step.\n\n## Migration Flow\n\n### Introduction\n\nMany tools, like the [konveyor kantra client](https://github.com/konveyor/kantra/) supports today the following flow. It generates an analysis report that users can use to review the issues reported, their criticality and what they should do to transform the code part of the message and/or links. \n```mermaid\n---\ntitle: Analysis and migration flow\n---\nflowchart LR\n    A[Tool] --\u003e |use rules|B[Scan Code]\n    B --\u003e |Generate|C[Analysis report]\n    C -..-\u003e |Execute|D[Transform]\n\n    style A fill:#e1f5fe\n    style C fill:#fff3e0\n```\n\u003e [!NOTE]\n\u003e The kantra client can be used to transform the code using openrewrite recipes.\n\nWhile this flow, which also includes instructions to be executed manually or by an external tool; IDE, etc., works pretty well, it suffers from a few limitations: \n\n- Lack of clear instructions to be executed during a transformation step according to the target technology to be used: openrewrite, AI, etc. \n- No order to play or execute the instructions,\n- The absence of `precondition` prevents determining the application's `eligibility` for analysis,\n- Difficulty to figure out which rules should be used part of a migration plan,\n- Complexity of the rule syntax to define the `match` condition with operators: `AND`, `OR` to indentify files where changes are needed\n\nWhile such limitations are not problematic for the users doing manually the transformation or executing a predefined migration plan, that could become a real challenge when it is needed to apply recipes or delegate to AI the responsibility to propose solutions. \n\nAI will certainly generate hallucinating results and this lack of predictability will discourage many users to rely on it. \n\nOn the other site, if you use as technology `openrewrite` or equivalent, the execution of the transformation steps could fail when by example maven compiles the code of the project analyzed due to changes applied to remove dependencies in a wrong order !\n\nThis is why it is important that we improve the existing flow to propose a more `controlled` or `enhanced` flow as depicted hereafter:\n\n```mermaid\n---\ntitle: Enhanced analysis and migration flow with instructions\n---\nflowchart LR\n    A[Tool with controlled flow] --\u003e |Use rules|B[Scan Code]\n    B --\u003e |Generate|C[Analysis report =\u003e Migration plan with tasks]\n    C --\u003e D{Do we have instructions?}\n    D --\u003e|Empty|E[No Action]\n    D --\u003e|if results|F{Select provider ?}\n    F --\u003e|User|G[Execute manual Tasks]\n    F --\u003e|AI|H[Prompt AI augmented messages]\n    F --\u003e|OpenRewrite|I[Apply Recipe]\n    G --\u003e J[Migrated Code]\n    H --\u003e J\n    I --\u003e J\n\n    style A fill:#e1f5fe\n    style C fill:#fff3e0\n    style E fill:#f3e5f5\n    style F fill:#fff8e1 \n```\n\n### Enhanced rule\n\nThe rule represents, per se, the contract definition between what we would like to discover within the code source scanned: java, properties, xml, json, maven or gradle files and what a provider should do to properly transform the code. \n\nAs presented hereafter, we have introduced different new fields part of the Rule YAML file:\n\n- `order`: The order to apply the instructions against the flow which is composed of several rules\n- `instructions`: List of instructions/tasks to be executed by a provider\n\n```yaml\n- ruleID: springboot-annotations-to-quarkus-00000\n  category: mandatory\n  description: Replace the Spring Boot Application Annotation with QuarkusMain\n  labels:\n    - konveyor.io/source=springboot\n    - konveyor.io/target=quarkus\n\n  message: \"Replace the Spring Boot Application Annotation with QuarkusMain\"\n  \n  when:\n    java.referenced:\n      location: ANNOTATION\n      pattern: org.springframework.boot.autoconfigure.SpringBootApplication\n\n  # Order to apply the instructions against the flow\n  order: 2\n  \n  # New section added to help to transform properly the code !\n  instructions:\n    ai:\n      - tasks:\n        - \"Remove the org.springframework.boot.autoconfigure.SpringBootApplication annotation from the main Spring Boot Application class\"\n    manual:\n      - todo: \"Remove the org.springframework.boot.autoconfigure.SpringBootApplication annotation from the main Spring Boot Application class\"\n    openrewrite:\n      - name: Migrate Spring Boot to Quarkus\n        preconditions:\n          - name: org.openrewrite.java.dependencies.search.ModuleHasDependency\n            groupIdPattern: org.springframework.boot\n            artifactIdPattern: spring-boot\n            version: '[3.5,)'\n        recipeList:\n          - dev.snowdrop.mtool.openrewrite.recipe.ReplaceSpringBootApplicationAnnotationWithQuarkusMain\n          - spring.recipe.dev.snowdrop.mtool.openrewrite.AddQuarkusRun\n        gav:\n          - dev.snowdrop.mtool:openrewrite-recipes:1.0.2-SNAPSHOT\n```\nThe list of the AI's tasks will be executed one by one as user's chat message. When code is generated, the user will be able to accept or reject the proposition.\n\nThe openrewrite section contains the list of the recipes and/or preconditions to be executed using the maven openrewrite goal and gav are maven dependencies\n\nTo make an application `elligible` for a migration plan and by consequence to let the `conditions` of the rules to be then executed, we have introduced\na new field for that purpose: `precondition`. If, during the `analysis` of the application, the `precondition` fails, then the process stops otherwise the conditions will be executed:\n\n```yaml\n- category: mandatory\n  customVariables: []\n  description: SpringBoot to Quarkus\n  effort: 1\n  labels:\n    - konveyor.io/source=springboot\n    - konveyor.io/target=quarkus\n  links: []\n  message: \"SpringBoot to Quarkus.\"\n  ruleID: spring-boot-parent-precondition-match\n  when:\n    # Example of precondition checking if we have a Spring Boot Parent version: 3.5.3\n    precondition: |\n      pom.dependency is (gavs='org.springframework.boot:spring-boot-starter-parent:3.5.3')\n    # If the precondition matches and is tru, then the condition's rule will be executed\n    condition: |\n      java.annotation is '@SpringBootApplication'\n...\n```\nTo simplify the adoption of the Rule as unit of work to analyse an application to be migrated, we have simplified the YAML query syntax to adopt a more user-friendly language more in line with the language that a user will use to search about something in a project. \n\nThe simplified query language syntax is defined using Antlr grammar and supports a query with a simple `clause` or multiple `clauses` separated with `AND`, `OR` operators\n\n```g4\ngrammar Query;\n\n@header {\npackage dev.snowdrop.parser.antlr;\n}\n\nsearchQuery: operation;\noperation\n    : operation AND operation #AndOperation\n    | operation OR operation  #OrOperation\n    | clause                  #SimpleClause\n    ;\n\nclause: fileType ('.' symbol)? ('is' | '=') (value | '(' keyValuePair (',' keyValuePair)* ')');\nfileType: 'JAVA' | 'java' | 'POM' | 'pom' | 'TEXT' | 'text' | 'PROPERTY' | 'property' | 'YAML' | 'yaml' | 'JSON' | 'json';\nsymbol: ID;\nkeyValuePair: key '=' value;\nkey: QUOTED_STRING | ID;\nvalue: QUOTED_STRING | ID;\nlogicalOp: AND | OR;\n\n// LEXER vocabulary of the language\nIS:    'is';\nAND:   'AND';\nOR:    'OR';\n\nID:            [a-zA-Z][a-zA-Z0-9-]*; // Identifier, allows dots for package names\nQUOTED_STRING: '\\'' ( ~('\\''|'\\\\') | '\\\\' . )* '\\''   // Single-quoted string\n             | '\"' ( ~('\"'|'\\\\') | '\\\\' . )* '\"';     // Double-quoted string\nEQUALS:        '=';\nDOT:           '.';\nCOMMA:         ',';\nLPAREN:        '(';\nRPAREN:        ')';\n\nWS:            [ \\t\\r\\n]+ -\u003e skip; // Skip whitespace\n```\n\nExamples of queries\n```yaml\n  when:\n    condition: java.annotation is 'org.springframework.boot.autoconfigure.SpringBootApplication'\n    condition: |\n      java.annotation is 'org.springframework.stereotype.Controller' OR\n      java.annotation is 'org.springframework.web.bind.annotation.GetMapping'\n    condition: |\n      pom.dependency is (gavs='org.springframework.boot:spring-boot-starter-web') AND\n      java.annotation is 'org.springframework.stereotype.Controller'\n```\n\n## Architecture of the PoC\n\nThe project uses the [Spring TODO](./applications/spring-boot-todo-app) example as the java project to be analyzed using augmented [rules](./cookbook/rules).\n\nThe poc has been designed using the following technology:\n- [Quarkus and Picocli](https://quarkus.io/guides/picocli) to manage the CLI part and commands \n- [konveyor jdt language server](https://github.com/konveyor/java-analyzer-bundle) to scan the java files to search about using the rule `when` condition.\n- [Openrewrite recipe](https://docs.openrewrite.org/concepts-and-explanations/recipes) to execute using the `maven rewrite` goal the transformations as defined part of the rule's instructions\n- [Antlr](https://www.antlr.org/) as parser tool to generate the code for the new Query Simpler language to be used to `Match` conditions\n- The different applications: `jdt-ls server`, `mvn command` are executed as OS processes using Java `ProcessBuilder`.\n\n## Requirements\n\n- Java 21 installed and Maven 3.9\n\n## Setup\n\nInstall the tool using the [jbang](https://jbang.dev) tool and the following command:\n```shell\njbang app install mtool@snowdrop/migration-tool\n```\n\n\u003e [!NOTE]\n\u003e To install a released version, append the version\n```shell\njbang app install mtool@snowdrop/migration-tool/1.0.0\n```\n\nOtherwise, if you plan to contribute to the project, git clone and compile it \n\n```shell\nmvn clean install -DskipTests\n```\n\n## Konveyor jdt-ls (optional)\n\nDownload the [konveyor language server](https://github.com/konveyor/java-analyzer-bundle) using the image packaging it:\n```shell\nset VERSION latest\n\nset ID $(podman create --name kantra-download quay.io/konveyor/kantra:$VERSION)\npodman cp $ID:/jdtls ./jdt/konveyor-jdtls\n```\n\n\u003e [!NOTE]\n\u003e If you're using bash and not fishell, remember to export the environment variables too!\n\n## mtool client's commands\n\nOur Migration Tool client (aka mtool) proposes 2 commands: \n\n- **[analyze](#scan-and-analyze)**: Scan the code source using the rules matching conditions and generate a JSON report augmented with the provider's instructions.\n- **[transform](#transform-your-application)**: Apply the transformation's instructions using as input the JSON report by using the chosen provider\n\n```shell\nUsage: mtool [-hV] [COMMAND]\nQuarkus mtool client able to scan, analyze and migrate a java application using\ninstructions\n  -h, --help      Show this help message and exit.\n  -V, --version   Print version information and exit.\nCommands:\n  analyze    Analyze a project for migration\n  transform  Transform a java application\n  help       Display help information about the specified command.\n```\n\nTo check the installed version:\n```shell\nmtool --version\n```\n\n### Scan and analyze\n\nTo analyze and generate the migration plan report (optional), execute this `analyze` command \n```shell\nUsage: mtool analyze [-v] [--jdt-ls-path=\u003cjdtLsPath\u003e]\n                   [--jdt-workspace=\u003cjdtWorkspace\u003e] [-o=\u003coutput\u003e]\n                   [-r=\u003crulesPath\u003e] [-s=\u003csource\u003e] [--scanner=\u003cscanner\u003e]\n                   [-t=\u003ctarget\u003e] \u003cappPath\u003e\nAnalyze a project for migration\n      \u003cappPath\u003e             Path to the Java project to analyze\n      --jdt-ls-path=\u003cjdtLsPath\u003e\n                            Path to JDT-LS installation (default: from config)\n      --jdt-workspace=\u003cjdtWorkspace\u003e\n                            Path to JDT workspace directory (default: from\n                              config)\n  -o, --output=\u003coutput\u003e     Export the analysing result using the format.\n                              Values: json\n  -r, --rules=\u003crulesPath\u003e   Path to rules directory (default: from config)\n  -s, --source=\u003csource\u003e     Source technology to consider for analysis\n      --scanner=\u003cscanner\u003e   Scanner tool to be used to analyse the code: jdtls,\n                              openrewrite\n  -t, --target=\u003ctarget\u003e     Target technology to consider for analysis\n  -v, --verbose             Enable verbose output\n```\n\nusing either the `quarkus:dev` goal or the jar file created from the previous maven command executed\n```shell\nmvn -pl migration-cli quarkus:dev -Dquarkus.args=\"analyze --jdt-ls-path /PATH/TO/java-analyzer-quarkus/jdt/konveyor-jdtls --jdt-workspace /PATH/TO/java-analyzer-quarkus/jdt -r /PATH/TO/java-analyzer-quarkus/rules ./applications/spring-boot-todo-app\"\n\nor \n\n❯ java -jar /PATH/TO/migration-tool-parent/migration-cli/target/quarkus-app/quarkus-run.jar analyze --jdt-ls-path /PATH/TO/java-analyzer-quarkus/jdt/konveyor-jdtls --jdt-workspace /PATH/TO/java-analyzer-quarkus/jdt -r /PATH/TO/java-analyzer-quarkus/rules ./applications/spring-boot-todo-app\"\nUsage: mtool [COMMAND]\nQuarkus mtool client able to scan, analyze and migrate a java application using\ninstructions\nCommands:\n  analyze    Analyze a project for migration\n  transform  Transform a java application\n  help       Display help information about the specified command.\n```\n\n\u003e [!TIP]\n\u003e To avoid to pass all the parameters to the command, you can use the \"defaults\" [application.properties](src/main/resources/application.properties) and just pass the path of the application to be analyzed\n\n```shell\nmtool analyze ../applications/spring-boot-todo-app\nmvn -pl migration-cli quarkus:dev -Dquarkus.args=\"analyze ../applications/spring-boot-todo-app\"\n```\n\nBy default, the tool generates a json report file having as file name: `analysing-report_yyyy-mm-dd_hh:mm.json`. If you want to generate this analysis report using the html format, then use the option `-o html`. \n\n```shell\nmtool analyze ../applications/spring-boot-todo-app -o html\nmvn -pl migration-cli quarkus:dev -Dquarkus.args=\"analyze ../applications/spring-boot-todo-app -o html\"\n```\n\n#### Scanner\n\nThe tool supports different scanners able to scan the code source:\n- konveyor jdt-ls\n- openrewrite recipe\n- maven\n- file and content search\n\nA scanner can be defined you launch the `analyze` command with the option `--scanner`. In this case, the tool will select it as default to scan and match a condition but will revert to one of the alternative scanners if the default don't support to search about: `\u003ctype\u003e.\u003csymbol\u003e` where \u003ctype\u003e can be: pom, java, properties, etc. and `symbol`: dependency, key, annotation, etc.\n\n## Transform your application\n\nNow that we have a migration plan containing the of the instructions to be executed by a provider, we can perform the transformation using the command `transform` where we pass as parameter the provider to be used.\n\n```shell\nUsage: mtool transform [-dv] [-p=\u003cprovider\u003e] \u003cappPath\u003e\nTransform a java application\n      \u003cappPath\u003e   Path to the Java project to transform\n  -d, --dry-run   Execute OpenRewrite in dry-run mode (preview changes without\n                    applying them)\n  -p, --provider=\u003cprovider\u003e\n                  Migration provider to use (ai, openrewrite, manual). Default:\n                    from migration.provider property\n  -v, --verbose   Enable verbose output\n```\n\n\u003e [!NOTE]\n\u003e The default provider is `openwrite` but you can use too: `manual` or `ai`\n\n### Openrewrite\n\nTo use openrewrite, execute the following command with or without the `dryRun` mode. If you use the `--dry-run` parameter, then openrewrite will generate `rewrite.patch` file(s) under the folder: `target/rewrite` of the analyzed project instead of changing the code directly !\n\n```shell\nmtool transform ../applications/spring-boot-todo-app -p openrewrite --dry-run\nor\nmvn -pl migration-cli quarkus:dev -Dquarkus.args=\"transform ../applications/spring-boot-todo-app -p openrewrite --dry-run\"\n```\n\nLog of the command executed \n```text\n2025-09-29 13:03:20,735 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) ✅ Starting transformation for project at: /Users/cmoullia/code/application-modernisation/migration-cli-parent/applications/spring-boot-todo-app\n2025-09-29 13:03:20,739 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) 📄 Loading migration tasks from: analysing-report_2025-09-26_14:05.json\n2025-09-29 13:03:20,879 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) 📋 Found 3 migration tasks to process\n2025-09-29 13:03:20,880 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) 🔄 Processing migration task: springboot-annotations-notfound-00000\n2025-09-29 13:03:20,881 WARN  [dev.sno.com.TransformCommand] (Quarkus Main Thread)    ⚠️  No OpenRewrite instructions found for task, skipping\n2025-09-29 13:03:20,882 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) 🔄 Processing migration task: springboot-annotations-to-quarkus-00000\n2025-09-29 13:03:28,091 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread)    ✅ OpenRewrite execution completed successfully\n2025-09-29 13:03:28,092 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) 🔄 Processing migration task: springboot-import-to-quarkus-00000\n2025-09-29 13:03:28,093 WARN  [dev.sno.com.TransformCommand] (Quarkus Main Thread)    ⚠️  No OpenRewrite instructions found for task, skipping\n2025-09-29 13:03:28,094 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) ----------------------------------------\n2025-09-29 13:03:28,095 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) --- Elapsed time: 7359 ms ---\n2025-09-29 13:03:28,096 INFO  [dev.sno.com.TransformCommand] (Quarkus Main Thread) ----------------------------------------\n```\n\n### AI\n\n\u003e [!IMPORTANT]\n\u003e Until now, this Quarkus client only supports to use Anthropic and Claude Sonnet 4 model\n\nTo be able to perform the transformation of the code, using AI, it is needed to set part of the `.env` file some new properties:\n```properties\nQUARKUS_LANGCHAIN4J_ANTHROPIC_CHAT_MODEL_MODEL_NAME=premium\nQUARKUS_LANGCHAIN4J_ANTHROPIC_BASE_URL=\u003cTHE_ANTHROPIC_API_SERVER\u003e\nQUARKUS_LANGCHAIN4J_ANTHROPIC_API_KEY=\u003cYOUR_ANTHROPIC_API_KEY\u003e\nQUARKUS_LANGCHAIN4J_ANTHROPIC_TIMEOUT=60\n```\nSource the `.env` file. \n\nDon't forget to generate first the `analysis migration plan` before to perform the transformation step\n```shell\nmtool analyze ../applications/demo-spring-boot-todo-app\"\n```\n\nYou can now execute the following command within a Java application analyzed \n\n```shell\npushd applications/spring-boot-todo-app\nmtool transform . -p ai\npopd\n```\nCheck the console to see the tasks executed and AI's reponses:\n```shell\n2025-10-08 13:28:56,037 INFO  [dev.sno.com.TransformCommand] (main) 🔄 Processing migration task: springboot-replace-bom-quarkus-0000\n2025-10-08 13:28:56,039 INFO  [dev.sno.tra.pro.imp.AiProvider] (main) Task: Add to the pom.xml file the Quarkus BOM dependency within the dependencyManagement section and the following dependencies: quarkus-arc, quarkus-core\n2025-10-08 13:28:56,039 INFO  [dev.sno.tra.pro.imp.AiProvider] (main) Task: The version of quarkus to be used and to included within the pom.xml properties is 3.31.3.\n2025-10-08 13:28:56,039 INFO  [dev.sno.tra.pro.imp.AiProvider] (main) Hello! I'm your AI migration assistant.\n2025-10-08 13:28:58,981 INFO  [dev.sno.tra.pro.ai.FileSystemTool] (main) Reading file: pom.xml\n2025-10-08 13:29:15,541 INFO  [dev.sno.tra.pro.imp.AiProvider] (main) ============= Claude response: Successfully added the Quarkus BOM dependency to the dependencyManagement section and included the quarkus-arc and quarkus-core dependencies. The Quarkus version property has also been added for version management.\n2025-10-08 13:29:18,549 INFO  [dev.sno.tra.pro.ai.FileSystemTool] (main) Reading file: pom.xml\n2025-10-08 13:29:33,810 INFO  [dev.sno.tra.pro.imp.AiProvider] (main) ============= Claude response: Successfully updated the Quarkus version to 3.31.3 in the properties section of the pom.xml file.\n2025-10-08 13:29:33,811 INFO  [dev.sno.tra.TransformationService] (main) ✅ Task completed successfully:    ✅ ai execution completed successfully\n...\n```\nIf the AI responses are not accurate, then you will have to adapt the instructions as described part of the different Rules YAML files available here: `cookbook/rules/ddd-springboot-****.yaml` !\n\n# Examples of migration scenario\n\n## Spring Boot Todo to Quarkus Application\n\nIf you follow the instructions detailed hereafter, you will be able to migrate the [Spring Boot Todo Application](applications/spring-boot-todo-app) to Quarkus. Until now, it is only possible to use the modules [JPA](https://quarkus.io/guides/spring-data-jpa), [Web/REST](https://quarkus.io/guides/spring-web) supported by Quarkus as Thymeleaf is a technology not available on Quarkus which is using Qute as [Web technology](https://quarkus.io/guides/web) !\n\nTo play with the migration-tool, git clone this project: https://github.com/snowdrop/migration-tool/ and compile it: `mvn clean package -DskipTests`.\n\nNext, analyze the project to migrate to generate the json migration report\n```shell\nmtool analyze ../applications/spring-boot-todo-app -r ../cookbook/rules/quarkus-spring --scanner openrewrite\nor\nmvn -pl migration-cli quarkus:dev -Dquarkus.args=\"analyze ../applications/spring-boot-todo-app -r ../cookbook/rules/quarkus-spring --scanner openrewrite\"\n```\n\nTransform the project (dry-run mode) and check the content of the `./target` directory (see rewrite folders and patch files)\n```shell\nmtool transform ../applications/spring-boot-todo-app -p openrewrite --dry-run\nor\nmvn -pl migration-cli quarkus:dev -Dquarkus.args=\"transform ../applications/spring-boot-todo-app -p openrewrite --dry-run\"\n```\n\nFinally migrate the Spring Boot Todo code to Quarkus\n```shell\nmtool transform ../applications/spring-boot-todo-app -p openrewrite\nor\nmvn -pl migration-cli quarkus:dev -Dquarkus.args=\"transform ../applications/spring-boot-todo-app -p openrewrite\"\n```\n\n\u003e [!NOTE]\n\u003e We recommend to create a git repository and branch within the \"spring-boot-todo-app\" to revert to the previous state if you apply the transformation\n\nAs documented, to play with the Quarkus application, launch it using the command:\n```\ncd applications/spring-boot-todo-app\nmvn package quarkus:dev -DskipTests\n```\n\n\u003e [!NOTE]\n\u003e it is needed to have podman or docker installed locally as quarkus will launch a MySQL testContainer to access the Todo DB.\n\nIf the Quarkus Todo application has started successfully then you can curl the REST endpoints\n```\ncurl http://127.0.0.1:8080/home\n\ncurl -X POST http://localhost:8080/home \\\n-H \"Content-Type: application/json\" \\\n-d '{\n\"title\": \"Prepare migration to Quarkus. Step 3\",\n\"description\": \"Analyser le projet et lister toutes les dépendances Spring Data.\",\n\"dueDate\": \"2025-12-24\"\n}'\n```\n\nEnjoy :-)\n\n## Tips\n\nThe `analyze` or `transform` commands can be executed using the quarkus uber jar file. Create in this case, an `.env` file, to configure properly the different properties needed:\n\n```properties\n# .env file content\nANALYZER_JDT_LS_PATH=jdt/konveyor-jdtls\nANALYZER_JDT_WORKSPACE_PATH=jdt\nANALYZER_RULES_PATH=cookbook/rules\n```\nNext source it and execute the following java commands within or outside the project to analyze/transform:\n\n```shell\njava -jar \u003cMIGRATION_CLI_JAR_PATH\u003e analyze $(pwd)/applications/spring-boot-todo-app -o json\njava -jar \u003cMIGRATION_CLI_JAR_PATH\u003e transform $(pwd)/applications/spring-boot-todo-app -p openrewrite --dry-run\n```\n\nIf you want to test separately the openrewrite recipes, then use the [openrewrite maven plugin command](https://docs.openrewrite.org/reference/rewrite-maven-plugin) top of a spring boot project. Take care that your project is under git control as code will be transformed !\n\n```shell\ncd applications/spring-boot-todo-app\nmvn -U org.openrewrite.maven:rewrite-maven-plugin:run \\\n   -Drewrite.recipeArtifactCoordinates=dev.snowdrop:java-analyzer-quarkus:1.0.2-SNAPSHOT \\\n   -Dorg.openrewrite.quarkus.spring.ReplaceSpringBootApplicationAnnotationWithQuarkusMain\n```\n\nInstead of changing the code, you can use the dryrun goal to get a patch\n```shell\ncd applications/spring-boot-todo-app\nmvn -U org.openrewrite.maven:rewrite-maven-plugin:dryRun \\\n   -Drewrite.recipeArtifactCoordinates=dev.snowdrop.mtool:openrewrite-recipes:1.0.2-SNAPSHOT \\\n   -Drewrite.activeRecipes=spring.recipe.dev.snowdrop.mtool.openrewrite.ReplaceSpringBootApplicationWithQuarkusMainAnnotation  \n```\nWhen done, open the diff patch generated: `/PATH/TO/spring-boot-todo-app/target/rewrite/rewrite.patch`\n\nTo execute several recipes aggregated in a yaml file placed at the root of the project, execute this command:\n```shell\nmvn -U org.openrewrite.maven:rewrite-maven-plugin:dryRun \\\n  -Drewrite.activeRecipes=dev.snowdrop.text.SearchText,dev.snowdrop.java.StandardJavaConventions,dev.snowdrop.java.spring.SearchSpringBootAnnotation \\\n  -Drewrite.recipeArtifactCoordinates=org.openrewrite:rewrite-java:8.62.4,org.openrewrite.recipe:rewrite-java-dependencies:1.42.0,dev.snowdrop.mtool:openrewrite-recipes:1.0.2-SNAPSHOT \\\n  -Drewrite.exportDatatables=true \\\n  -Drewrite.configLocation=my-rewrite-1.yml\n...\n[WARNING] These recipes would make changes to applications/spring-boot-todo-app/my-rewrite.yml:\n[WARNING]     dev.snowdrop.text.SearchText\n[WARNING]         org.openrewrite.text.Find: {find=public class TaskController}\n[WARNING] Patch file available:\n[WARNING]     /Users/cmoullia/code/application-modernisation/migration-cli-parent/applications/spring-boot-todo-app/target/rewrite/rewrite.patch\n[WARNING] Estimate time saved: 40m\n[WARNING] Run 'mvn rewrite:run' to apply the recipes.  \n```\n\nCommand using another YAML example\n```shell\nmvn -U org.openrewrite.maven:rewrite-maven-plugin:dryRun \\\n  -Drewrite.activeRecipes=dev.snowdrop.java.spring.SearchSpringBootAnnotation \\\n  -Drewrite.recipeArtifactCoordinates=org.openrewrite:rewrite-java:8.62.4,org.openrewrite.recipe:rewrite-java-dependencies:1.42.0,dev.snowdrop.mtool:openrewrite-recipes:1.0.2-SNAPSHOT \\\n  -Drewrite.exportDatatables=true \\\n  -Drewrite.configLocation=my-rewrite-2.yml\n```\n\n## TODO\n\n| Task   | Status | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Comment |\n|--------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|\n| MT-001 |        | Check what [spring-migrator-tool](https://github.com/spring-projects-experimental/spring-boot-migrator/blob/main/components/sbm-support-boot/src/main/resources/recipes/initialize-spring-boot-migration.yaml) did to reuse some ideas to configure the instructions using `Actions` able to configure the recipe. The [action](https://github.com/spring-projects-experimental/spring-boot-migrator/blob/main/components/sbm-core/src/main/java/org/springframework/sbm/build/migration/actions/AddMavenDependencyManagementAction.java)'s definition is used as input to apply the corresponding openrewrite's [recipe](https://github.com/spring-projects-experimental/spring-boot-migrator/blob/main/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java#L376). |         |\n| MT-002 |        | Investigate if the language server could be replaced using Openrewrite concepts such as: [searchResult](https://docs.openrewrite.org/concepts-and-explanations/markers#searchresult)'s marker, [DataTable](https://docs.openrewrite.org/authoring-recipes/data-tables#writing-a-recipe-that-produces-a-data-table) or [Scanning recipe](https://docs.openrewrite.org/concepts-and-explanations/recipes#scanning-recipes)                                                                                                                                                                                                                                                                                                                                                                                            |         |\n| MT-003 |        | Discuss and define the level of granularity between what the rule targets to do and the steps/actions that the provider will support. Such a granularity can start with a `1` to `1` relation to a `1` to `many` but where the `many` is executed as a composite component or pipeline: https://docs.openrewrite.org/concepts-and-explanations/recipes#recipe-execution-pipeline, https://docs.openrewrite.org/concepts-and-explanations/recipes#scanning-recipes                                                                                                                                                                                                                                                                                                                                                   |         |\n| MT-004 |        | What about creating a migration plan like this one: https://docs.openrewrite.org/recipes/java/migrate/search/planjavamigration ?                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |         |\n| MT-005 |        | Do we have to integrate a workflow engine part of the solution to externalize the sequential approach of the openrewrite framework within a separate engine ?                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |         |\n\n\n## Deprecated\n\n### Start using the JdtlsFactory Main application\n\nBefore to run the server and client, configure the following system properties or override the Quarkus properties[application.properties](src/main/resources/application.properties):\n- `JDT_WKS`: Path of the folder containing the jdt-ls workspace, .metadata and log. Default: `./jdt/`\n- `JDT_LS_PATH`: Path of the jdt language server folder. Default: `./jdt/konveyor-jdtls`\n- `LS_CMD`: Language server command to be executed. Default: `io.konveyor.tackle.ruleEntry`, etc\n- `APP_PATH`: Path of the java project to analyze. Default: `./applications/spring-boot-todo-app`\n- `RULES_PATH`: Path of the rules. Default: `./rules`\n\n```shell\nmvn exec:java\n```\n\n### Trick to path the eclipse osgi server\n\nHere is the trick to do to add a bundle to the OSGI jdt-ls server. This step is optional as we will pass the bundle path as initialization parameter to the language server !\n\nEdit the `config.ini` file corresponding to your architecture: mac, linux, mac_arm under the folder konveyor-jdtls/config_\u003cARCH\u003e\n\nModify within the config.ini file the `osgi.bundles` property and include after the `org.apache.commons.lang3...` jar the BundleSymbolicName of: java-analyzer-bundle.core-1.0.2-SNAPSHOT.jar\n```text\nosgi.bundles=...org.apache.commons.lang3_3.14.0.jar@4,reference\\:file\\:java-analyzer-bundle.core-1.0.2-SNAPSHOT.jar@2,...\n```\n\nCopy the java-analyzer-bundle.core-1.0.2-SNAPSHOT.jar file from the path `konveyor-jdtls/java-analyzer-bundle/java-analyzer-bundle.core/target/` to the `plugins` folder\n\n### Download jdt-ls\n\nAlternatively, you can also download the [Eclipse JDT Language Server](https://github.com/eclipse-jdtls/eclipse.jdt.ls):\n\n```shell\nwget https://www.eclipse.org/downloads/download.php?file=/jdtls/milestones/1.50.0/jdt-language-server-1.50.0-202509041425.tar.gz \u003e jdt-language-server-1.50.0.tar.gz\nmkdir jdt-ls\ntar -vxf jdt-language-server-1.50.0.tar.gz -C jdt-ls\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowdrop%2Fmigration-tool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnowdrop%2Fmigration-tool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowdrop%2Fmigration-tool/lists"}