You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenRewrite自定义Recipe无法运行,报错类找不到求助

问题重现

1. 自定义Recipe代码

package com.yourorg;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.EqualsAndHashCode;
import lombok.Value;
import org.openrewrite.*;
import org.openrewrite.internal.lang.NonNull;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.tree.J;

// Making your recipe immutable helps make them idempotent and eliminates categories of possible bugs.
// Configuring your recipe in this way also guarantees that basic validation of parameters will be done for you by rewrite.
// Also note: All recipes must be serializable. This is verified by RewriteTest.rewriteRun() in your tests.
@Value
@EqualsAndHashCode(callSuper = false)
public class SayHelloRecipe extends Recipe {
    @Option(displayName = "Fully Qualified Class Name",
            description = "A fully qualified class name indicating which class to add a hello() method to.",
            example = "com.yourorg.FooBar")
    @NonNull
    String fullyQualifiedClassName;

    // All recipes must be serializable. This is verified by RewriteTest.rewriteRun() in your tests.
    @JsonCreator
    public SayHelloRecipe(@NonNull @JsonProperty("fullyQualifiedClassName") String fullyQualifiedClassName) {
        this.fullyQualifiedClassName = fullyQualifiedClassName;
    }

    @Override
    public String getDisplayName() {
        return "Say Hello";
    }

    @Override
    public String getDescription() {
        return "Adds a \"hello\" method to the specified class.";
    }

    @Override
    public TreeVisitor<?, ExecutionContext> getVisitor() {
        // getVisitor() should always return a new instance of the visitor
        return new SayHelloVisitor();
    }

    public class SayHelloVisitor extends JavaIsoVisitor<ExecutionContext> {
        private final JavaTemplate helloTemplate =
                JavaTemplate.builder( "public String hello() { return \"Hello from #{}!\"; }").build();

        @Override
        public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext executionContext) {
            // Don't make changes to classes that don't match the fully qualified name
            if (classDecl.getType() == null || !classDecl.getType().getFullyQualifiedName().equals(fullyQualifiedClassName)) {
                return classDecl;
            }

            // Check if the class already has a method named "hello".
            boolean helloMethodExists = classDecl.getBody().getStatements().stream()
                    .filter(statement -> statement instanceof J.MethodDeclaration)
                    .map(J.MethodDeclaration.class::cast)
                    .anyMatch(methodDeclaration -> methodDeclaration.getName().getSimpleName().equals("hello"));

            // If the class already has a `hello()` method, don't make any changes to it.
            if (helloMethodExists) {
                return classDecl;
            }

            // Interpolate the fullyQualifiedClassName into the template and use the resulting LST to update the class body
            classDecl = classDecl.withBody( helloTemplate.apply(new Cursor(getCursor(), classDecl.getBody()),
                    classDecl.getBody().getCoordinates().lastStatement(),
                    fullyQualifiedClassName ));

            return classDecl;
        }
    }
}

2. Maven插件配置

<plugin>
    <groupId>org.openrewrite.maven</groupId>
    <artifactId>rewrite-maven-plugin</artifactId>
    <version>5.20.0</version>
    <configuration>
        <activeRecipes>
            <recipe>com.yourorg.sayHelloToFooBar</recipe>
        </activeRecipes>
    </configuration>
</plugin>

3. rewrite.yml配置

---
type: specs.openrewrite.org/v1beta/recipe
name: com.yourorg.sayHelloToFooBar
recipeList:
  - com.yourorg.SayHelloRecipe:
      fullyQualifiedClassName: com.yourorg.FooBar

4. 错误日志

[ERROR] Recipe validation error in com.yourorg.SayHelloRecipe: Recipe class com.yourorg.SayHelloRecipe cannot be found
[ERROR] Recipe validation error in com.yourorg.SayHelloRecipe: Recipe class com.yourorg.SayHelloRecipe cannot be found
[ERROR] Recipe validation error in com.yourorg.SayHelloRecipe: Recipe class com.yourorg.SayHelloRecipe cannot be found
[ERROR] Recipe validation errors detected as part of one or more activeRecipe(s). Execution will continue regardless.


排查与解决方法

1. 先编译自定义Recipe代码

OpenRewrite Maven插件只能读取已编译的class文件,直接运行插件会找不到未编译的代码。先执行mvn compile编译你的Recipe类,再运行Rewrite插件。

2. 绑定插件到编译后阶段

修改Maven插件配置,将其绑定到verify阶段(该阶段在compile之后执行),确保代码先编译再执行Rewrite:

<plugin>
    <groupId>org.openrewrite.maven</groupId>
    <artifactId>rewrite-maven-plugin</artifactId>
    <version>5.20.0</version>
    <executions>
        <execution>
            <id>rewrite-run</id>
            <phase>verify</phase>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <activeRecipes>
            <recipe>com.yourorg.sayHelloToFooBar</recipe>
        </activeRecipes>
    </configuration>
</plugin>

之后执行mvn verify即可自动完成编译+Rewrite流程。

3. 确认rewrite.yml的路径

rewrite.yml必须放在项目的src/main/resources/META-INF/rewrite/目录下,OpenRewrite会自动扫描该路径下的配置文件,路径错误会导致插件无法加载你的组合Recipe。

4. 检查包名与类名的一致性

确保代码中的包名com.yourorg、类名SayHelloRecipe,与rewrite.yml、Maven配置中的引用完全一致(Java类名大小写敏感)。

5. 排查Lombok编译问题

你的Recipe使用了Lombok注解,需确保Maven已正确配置Lombok插件,否则编译后的class文件会不完整,导致OpenRewrite无法识别为有效Recipe:

<!-- 添加Lombok依赖 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version>
    <scope>provided</scope>
</dependency>

<!-- 添加Lombok Maven插件 -->
<plugin>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok-maven-plugin</artifactId>
    <version>1.18.30.0</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>delombok</goal>
            </goals>
        </execution>
    </executions>
</plugin>

内容的提问来源于stack exchange,提问作者fan fan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:17:51