Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Feedback from a 152k-line Java 8 to 25 migration: the silent behavioural changes that cost the most, and which have no recipe

オープン
#1,227 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
32/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
活発
技術スタック
java, spring

調査の方向性

まず、4つの移行ギャップと、rewrite-migrate-java、rewrite-spring、rewrite-hibernate、rewrite-static-analysis に存在する META-INF/rewrite/*.yml ファイルを読みます。最初に切り出すべき項目を明確にします。完了とは、選択した移行ケースをカバーする、合意済みでスコープが明確な recipe または diagnostic があることを意味します。

索引モデルが issue の本文から書いたものです。

説明

Context

I ran a controlled A/B experiment migrating a 152,000-line application (Spring 3.0.5 to 6.2,
Hibernate 3.5.5 to 6.6, Java 8 to 25, JUnit 4/3 to 5) twice: once using OpenRewrite heavily, once
with OpenRewrite forbidden and everything done by hand. Both arms succeeded and both landed at the
same place.

The useful finding for you is where the time actually went, because it was not where I
expected. Recipes handled the mechanical work well - the two arms converged to within 1% on
namespace rewriting (396 vs 392 jakarta imports in .java, 201 vs 202 in AspectJ ITDs). The
dominant cost in both arms was diagnosing silent behavioural change: things that compile
fine, produce no warning, and fail at runtime.

Below are the four that cost the most. Each is verified to have no recipe and no detection in
rewrite-migrate-java 3.42.1, rewrite-spring 6.37.1, rewrite-hibernate 2.25.0 or
rewrite-testing-frameworks 3.44.0, by grepping every META-INF/rewrite/*.yml. I am filing them
together because they are one theme; happy to split them, and happy to contribute any of them.

I have opened the Spring 6 trailing-slash case separately as

  • openrewrite/rewrite-spring#1142, since that one already has a recipe that is simply unreachable.

1. Surefire 3 silently ignores forkMode — 158 failing tests from one cause

forkMode was removed in maven-surefire-plugin 3.0.0-M8. It is not an error and produces no
warning; the parameter is ignored. A suite relying on forkMode=always for isolation then leaks
static state between test classes.

This was the single largest failure cluster of the entire migration - 158 tests - and it
presented as a mass application regression rather than as a build-configuration change.

  • This was requested in openrewrite/rewrite#2644 and closed with:

Closing - this recipe request for Surefire plugin migration would belong in
rewrite-static-analysis or rewrite-migrate-java rather than the core rewrite repo.
Consider filing there if still desired.

So: filing it here as invited. The mapping is documented and mechanical -
forkMode=always to reuseForks=false with forkCount=1, forkMode=once to
reuseForks=true, forkMode=never to forkCount=0. It matters much more now than in 2023,
because the JUnit 5 recipes bump surefire to 3.x, so the migration itself introduces the
breakage.

2. GenerationType.AUTO changes meaning between Hibernate 3/4 and 5+

Under Hibernate 3 with a MySQL or HSQLDB dialect, AUTO meant a native identity column. From
Hibernate 5 it prefers a sequence or table generator, which defers the INSERT past
persist()
. Code that reads the generated identifier straight after persist() breaks, and
the failures point at the application rather than at the ORM.

No recipe changes it (GenerationType appears only inside an unrelated example). Both arms
independently hand-edited the same 19 entities to GenerationType.IDENTITY.

Belongs in rewrite-hibernate, as part of the MigrateToHibernate5x/6x chain: rewrite AUTO to
IDENTITY when a MySQL/HSQLDB-family dialect is configured, or - more conservatively - mark every
@GeneratedValue(strategy = AUTO) for review.

3. @ModelAttribute parameters became data-bound from URI template variables

Since Spring 3.1, URI template variables are bound onto @ModelAttribute arguments. On an
entity-backed @ModelAttribute this silently overwrites the identifier from the path, and
Hibernate then rejects the update ("identifier of an instance was altered"). The fix is
@ModelAttribute(binding = false) or an @InitBinder exclusion.

86 parameters needed it here. No recipe addresses it. Belongs in rewrite-spring.

4. No AspectJ support, and no warning that files are being skipped

OpenRewrite has no .aj parser, so AspectJ inter-type declarations are invisible to every
recipe. I could not find an existing issue for this - ".aj" parser and inter-type declaration
both return zero results across the org.

Concretely: 197 .aj files, of which 47 contained 201 javax.* import lines that every
jakarta recipe silently left untouched, and 72 were test ITDs that declare @RunWith,
@ContextConfiguration and the @Test methods themselves. The consequence was decisive - the
OpenRewrite arm abandoned the JUnit 5 objective entirely because the declarations it needed to
change were unreachable, while the hand-editing arm completed it across 86 files.

A full AspectJ parser is obviously a large ask and I am not asking for it. But detecting .aj
files in the source set and reporting "N files are outside the reach of every recipe"
is small,
and would convert a silent and misleading success into a known gap. As it stands rewrite:run
reports success on a project where a substantial share of the relevant declarations were never
examined.

Why I think this is worth your time

Where recipes applied, they were clearly better than non-deterministic LLM inference work: faster, more consistent, and they
produced a reviewable diff. The reason the recipe-using experiment did not win overall is that the
mechanical share of a fifteen-year framework migration is smaller than it looks, and none of the
four items above are covered. Items 1 and 2 in particular are narrow, mechanical, and would have
removed the two largest failure clusters I hit.

主要言語
Java
スター
159
フォーク
130
平均マージ
6時間 49分
マージ済み PR(30日)
47

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

openrewrite/rewrite-migrate-java のほかの issue

openrewrite/rewrite-migrate-java の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。