Skip to content

Parent-delegate AnnotationMatcher in RecipeClassLoader - #8438

Merged
knutwannheden merged 2 commits into
mainfrom
wiry-peacock
Aug 10, 2026
Merged

Parent-delegate AnnotationMatcher in RecipeClassLoader#8438
knutwannheden merged 2 commits into
mainfrom
wiry-peacock

Conversation

@knutwannheden

@knutwannheden knutwannheden commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Motivation

A recipe run on 8.88.3 fails with a LinkageError the first time MissingOverrideAnnotation reaches AnnotationService#matches:

java.lang.LinkageError: loader constraint violation: loader 'app' wants to load class
org.openrewrite.java.AnnotationMatcher. A different class with the same name was previously
loaded by io.moderne.cli.recipe.CliRecipeClassLoader.
  org.openrewrite.java.service.AnnotationService.matches(AnnotationService.java:38)
  org.openrewrite.staticanalysis.MissingOverrideAnnotation$MissingOverrideAnnotationVisitor.visitMethodDeclaration

MethodMatcher is already in the list for the same reason; AnnotationMatcher is the same shape and was simply missed. It is the only such gap: every other type in a org.openrewrite.java.service public signature (JavaVisitor, Tree, SourceFile, Cursor, ExecutionContext, J, JContainer, JRightPadded, Span, trait.Comments.Placement, internal.CommentService/NamingService) is already delegated, and no language module subclasses AnnotationService.

Summary

  • org.openrewrite.java.AnnotationMatcher joins MethodMatcher and TypeNameMatcher in PARENT_DELEGATED_PREFIXES.

Test plan

  • New RecipeClassLoaderTest#matcherTypesInSharedSignaturesShouldDelegateToParent gives both loaders a copy of AnnotationMatcher and MethodMatcher and asserts each resolves to the parent; verified failing on AnnotationMatcher before the fix (MethodMatcher already passed) and passing after.
  • ./gradlew :rewrite-core:test --tests "org.openrewrite.marketplace.RecipeClassLoaderTest" passes, 11 tests.

Release note

This is a regression introduced in 8.88.3 and affects any recipe reaching AnnotationService#matches from a recipe bundle, which includes MissingOverrideAnnotation. The Moderne CLI resolves rewrite as latest.release, so it needs a rebuild once this ships.

`AnnotationService#matches` names `AnnotationMatcher` in its descriptor. Since #8427
shared `org.openrewrite.java.service` with the parent, a recipe-side caller and the
host-loaded service resolved that parameter to different classes, so the JVM raised a
loader constraint violation on the call.
@github-project-automation github-project-automation Bot moved this from In Progress to Ready to Review in OpenRewrite Aug 10, 2026
@knutwannheden
knutwannheden merged commit cf17012 into main Aug 10, 2026
1 check passed
@knutwannheden
knutwannheden deleted the wiry-peacock branch August 10, 2026 10:24
@github-project-automation github-project-automation Bot moved this from Ready to Review to Done in OpenRewrite Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants