Skip to content

Add TypeNameMatcher to RecipeClassLoader allowlist#7582

Merged
jkschneider merged 1 commit intomainfrom
dt-fix-typenamematcher-allowlist
May 6, 2026
Merged

Add TypeNameMatcher to RecipeClassLoader allowlist#7582
jkschneider merged 1 commit intomainfrom
dt-fix-typenamematcher-allowlist

Conversation

@pdelagrave
Copy link
Copy Markdown
Contributor

Problem

RecipeClassLoader.PARENT_DELEGATED_PREFIXES includes org.openrewrite.java.internal.TypesInUse so that recipes and the host (e.g. mod CLI, recipe worker) agree on a single shared TypesInUse Class. The signature of TypesInUse.hasTypeMatching was recently extended with a new parameter type org.openrewrite.java.TypeNameMatcher, but TypeNameMatcher was not added to the allowlist.

When a recipe-loaded UsesType.visit() invokes TypesInUse.hasTypeMatching(TypeNameMatcher, boolean):

  • UsesType is loaded by the recipe classloader, which resolves TypeNameMatcher to its own copy from the recipe artifact's bundled rewrite-core.
  • TypesInUse is loaded by the parent classloader, which resolves TypeNameMatcher to the parent's copy.
  • The JVM enforces a loader constraint and throws java.lang.LinkageError because the two classloaders disagree on TypeNameMatcher's Class identity.

The error fires once per (recipe instance, source file) pair, with each row writing a multi-KB stack trace to the SourcesFileErrors data table. On Spring-heavy runs this can produce hundreds of MB of error rows per repo.

Solution

Add org.openrewrite.java.TypeNameMatcher to PARENT_DELEGATED_PREFIXES. Both classloaders then resolve TypeNameMatcher via the parent and share a single Class object, satisfying the loader constraint.

Validation

Validated locally:

Before fix After fix
SourcesFileErrors rows 111,767 4
SourcesFileErrors.csv.gz size 1.5 MB 608 bytes
LinkageError rows 111,763 0

(The 4 remaining rows are an unrelated K.Return.getPrefix() NPE in rewrite-kotlin, not affected by this change.)

The same one-line fix is also being submitted to the parallel io.moderne.recipe.RecipeClassLoader in moderneinc/moderne-recipe-loading-commons for the v1 worker path.

`RecipeClassLoader.PARENT_DELEGATED_PREFIXES` includes `org.openrewrite.java.internal.TypesInUse`, ensuring the parent and child classloaders share one `TypesInUse` Class object. The signature of `TypesInUse.hasTypeMatching` was extended with a new parameter type, `org.openrewrite.java.TypeNameMatcher`, but `TypeNameMatcher` was not added to the allowlist.

The result: when a recipe-loaded `UsesType.visit()` invokes `TypesInUse.hasTypeMatching(TypeNameMatcher, boolean)`, the recipe classloader resolves `TypeNameMatcher` to its own copy (from the recipe artifact's bundled rewrite-core), while the parent-loaded `TypesInUse` was compiled against the parent's `TypeNameMatcher`. The JVM enforces a loader constraint and throws `LinkageError` because the two classloaders disagree on `TypeNameMatcher`'s identity.

Each error fires once per `(recipe instance, source file)` pair and writes a multi-KB stack trace to the `SourcesFileErrors` data table. On Spring-heavy multi-recipe runs this produced hundreds of MB to tens of GB per repo.

Adding `TypeNameMatcher` to the allowlist forces both classloaders to resolve to the same `Class` object, satisfying the loader constraint.

Validated locally with `mod` CLI: running `io.moderne.java.spring.boot4.SpringBoot4BestPractices` on a Spring-using repo dropped `SourcesFileErrors` from 111,767 rows to 4, eliminating all LinkageError occurrences.
@pdelagrave pdelagrave self-assigned this May 6, 2026
@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite May 6, 2026
@github-project-automation github-project-automation Bot moved this from In Progress to Ready to Review in OpenRewrite May 6, 2026
@jkschneider jkschneider merged commit 05970b0 into main May 6, 2026
1 check passed
@jkschneider jkschneider deleted the dt-fix-typenamematcher-allowlist branch May 6, 2026 21:43
@github-project-automation github-project-automation Bot moved this from Ready to Review to Done in OpenRewrite May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants