Skip to content

Conversation

timtebeek
Copy link
Member

@timtebeek timtebeek commented Sep 16, 2025

Summary

  • Implements a migration recipe for JEP 512 (Compact Source Files and Instance Main Methods)
  • Converts public static void main(String[] args) to instance void main() when args is unused
  • Integrated into both Java 21 and Java 25 migration recipes

Changes

  • Added MigrateMainMethodToInstanceMain recipe class that:

    • Detects main methods with unused String[] args parameter
    • Removes public and static modifiers
    • Removes the unused parameter when safe
    • Preserves formatting and annotations
    • Uses robust variable reference detection via VariableReferences.findRhsReferences()
  • Comprehensive test suite with 12 test cases covering:

    • Basic migration when args is unused
    • Preservation of args when used
    • Edge cases (annotations, different signatures, empty bodies)
  • Added recipe to Java 25 migration path (JEP 512 was introduced in Java 21 but is particularly relevant for modern Java)

Test Plan

  • All unit tests pass (./gradlew test --tests "*MigrateMainMethodToInstanceMainTest*")
  • Recipe correctly identifies unused parameters
  • Formatting is preserved correctly
  • Integration testing with real-world codebases
  • Review by maintainers

Related

timtebeek and others added 4 commits September 16, 2025 20:44
Implements a migration recipe to convert `public static void main(String[] args)`
to instance `void main()` when the args parameter is unused, as introduced in
JEP 512 (Java 21+).

The recipe:
- Detects main methods with unused String[] args parameter
- Removes public and static modifiers
- Removes the unused parameter
- Preserves formatting and annotations
- Only applies to Java 21+ codebases

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-project-automation github-project-automation bot moved this to In Progress in OpenRewrite Sep 16, 2025
@timtebeek timtebeek self-assigned this Sep 16, 2025
Refactored the modifier filtering logic to use OpenRewrite's ListUtils.filter
and ListUtils.mapFirst utilities for cleaner and more idiomatic code.
@timtebeek timtebeek marked this pull request as ready for review September 16, 2025 19:29
@timtebeek timtebeek added the recipe Recipe requested label Sep 16, 2025
@timtebeek timtebeek moved this from In Progress to Ready to Review in OpenRewrite Sep 16, 2025
@timtebeek timtebeek merged commit 72818ad into main Sep 16, 2025
2 checks passed
@timtebeek timtebeek deleted the feature/jep-512-instance-main-methods branch September 16, 2025 19:42
@github-project-automation github-project-automation bot moved this from Ready to Review to Done in OpenRewrite Sep 16, 2025
mergify bot added a commit to robfrank/linklift that referenced this pull request Oct 7, 2025
…17.1 to 3.18.0 [skip ci]

[//]: # (dependabot-start)
⚠️ \*\*Dependabot is rebasing this PR\*\* ⚠️
Rebasing might not happen immediately, so don't worry if this takes some time.
Note: if you make any changes to this PR yourself, they will take precedence over the rebase.
---
[//]: # (dependabot-end)
Bumps [org.openrewrite.recipe:rewrite-migrate-java](https://github.com/openrewrite/rewrite-migrate-java) from 3.17.1 to 3.18.0.
Release notes

*Sourced from [org.openrewrite.recipe:rewrite-migrate-java's releases](https://github.com/openrewrite/rewrite-migrate-java/releases).*

> 3.18.0
> ------
>
> What's Changed
> --------------
>
> * Add OpenRewrite recipe for JEP 512 instance main methods by [`@​timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#852](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/852)
> * Generate Guava InlineMethodCalls recipes using [openrewrite/rewrite#6059](https://redirect.github.com/openrewrite/rewrite/issues/6059) by [`@​timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#853](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/853)
> * Run CI on Java 25 by [`@​timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#851](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/851)
> * Generate recipes for Guava 33.5.0-jre by [`@​timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#854](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/854)
> * Use type tables for tests by [`@​knutwannheden`](https://github.com/knutwannheden) in [openrewrite/rewrite-migrate-java#856](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/856)
>
> **Full Changelog**: <openrewrite/rewrite-migrate-java@v3.17.1...v3.18.0>


Commits

* [`5a66684`](openrewrite/rewrite-migrate-java@5a66684) Use type tables for tests ([#856](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/856))
* [`1111d4a`](openrewrite/rewrite-migrate-java@1111d4a) Migrate away from micrometer nullable annotations
* [`257d4bc`](openrewrite/rewrite-migrate-java@257d4bc) Generate recipes for Guava 33.5.0-jre ([#854](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/854))
* [`041816a`](openrewrite/rewrite-migrate-java@041816a) Run CI on Java 25 ([#851](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/851))
* [`bb024d5`](openrewrite/rewrite-migrate-java@bb024d5) Generate Guava InlineMethodCalls recipes using [openrewrite/rewrite#6059](https://redirect.github.com/openrewrite/rewrite/issues/6059) ([#853](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/853))
* [`2a1a482`](openrewrite/rewrite-migrate-java@2a1a482) [Auto] SDKMAN! Java candidates as of 2025-09-22T1016
* [`72818ad`](openrewrite/rewrite-migrate-java@72818ad) Add OpenRewrite recipe for JEP 512 instance main methods ([#852](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/852))
* See full diff in [compare view](openrewrite/rewrite-migrate-java@v3.17.1...v3.18.0)
  
[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility\_score?dependency-name=org.openrewrite.recipe:rewrite-migrate-java&package-manager=maven&previous-version=3.17.1&new-version=3.18.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
  
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show  ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
recipe Recipe requested
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

1 participant