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

OpenRewrite自定义Java Recipe报错:LST含缺失/无效类型信息

问题

我正在用OpenRewrite开发迁移Recipe,将Play Framework控制器转换为Spring Boot REST控制器。还没在visitor中编写任何LST修改代码,就遇到了java.lang.IllegalStateException错误,提示LST包含缺失或无效类型信息,指向方法调用ok("Hello, World!")。

错误栈

java.lang.IllegalStateException: LST contains missing or invalid type information
MethodInvocation->Return->Block->MethodDeclaration->Block->ClassDeclaration->CompilationUnit
/*~~(MethodInvocation type is missing or malformed)~~>*/ok("Hello, World!")

    at org.openrewrite.java.Assertions.assertValidTypes(Assertions.java:87)
    at org.openrewrite.java.Assertions.validateTypes(Assertions.java:57)
    at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:305)
    at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:133)
    at org.openrewrite.test.RewriteTest.rewriteRun(RewriteTest.java:128)
    at com.yourorg.NewPlayToSpringControllersRecipeTest.migratePlayControllerAndMethodToSpringRestController(NewPlayToSpringControllersRecipeTest.java:23)
    at java.base/java.lang.reflect.Method.invoke(Method.java:569)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

测试方法代码

package com.yourorg;

import org.junit.jupiter.api.Test;
import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.java.Assertions;
import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

public class NewPlayToSpringControllersRecipeTest implements RewriteTest {


    @Override
    public void defaults(RecipeSpec spec) {
        spec.recipe(new NewPlayToSpringControllersRecipe())
          .parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(),
            "jackson-databind", "jackson-core", "jackson-annotations",
            "spring-web-6.1.+", "play_2.11-2.7.+"));
    }

    @Test
    void migratePlayControllerAndMethodToSpringRestController() {
        rewriteRun(
          Assertions.java(
            """
              package com.example;

              import play.mvc.Controller;
              import play.mvc.Result;

              public class MyController extends Controller {
                  
                  public Result sayHello() {
                      return ok("Hello, World!");
                  }
              }
              """
          )
        );
    }
}

Recipe的getVisitor方法代码

package com.yourorg;

import org.openrewrite.ExecutionContext;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.*;
import org.openrewrite.java.tree.J;

public class NewPlayToSpringControllersRecipe extends Recipe {

    @Override
    public String getDisplayName() {
        return "Migrate play framework controllers to spring boot REST controllers";
    }

    @Override
    public String getDescription() {
        return "Transforms Play Framework controllers to Spring Boot REST controllers by removing the Play-specific superclass " +
                "and adding the @RestController annotation.";
    }


    @Override
    public TreeVisitor<?, ExecutionContext> getVisitor() {
        return new JavaIsoVisitor<ExecutionContext>() {
            @Override
            public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration cd, ExecutionContext executionContext) {
                System.out.println("visitClassDeclaration\n" + TreeVisitingPrinter.printTree(getCursor()));
                return super.visitClassDeclaration(cd, executionContext);
            }
        };
    }
}
解决方案
  • 问题根源:OpenRewrite测试框架默认会验证LST的类型信息完整性。ok("Hello, World!")是Play框架Controller类的静态方法,但测试时的classpath未正确加载Play依赖,导致解析器无法识别该方法的类型,触发类型验证失败。
  • 修复步骤:
    1. 确保Play依赖正确引入:检查classpathFromResources中指定的play_2.11-2.7.+是否能在项目资源classpath中找到对应JAR包。如果用Maven/Gradle管理依赖,建议直接通过构建工具引入Play的play-mvc依赖,而非从资源加载。
    2. 临时禁用类型验证:若仅需测试Recipe逻辑、暂时不关心类型检查,可在测试中关闭验证:
      rewriteRun(
        spec -> spec.noValidate(),
        Assertions.java(/* 原测试代码 */)
      );
      
    3. 正确配置JavaParser的classpath:如果用Maven,推荐使用JavaParser.fromJavaVersion().classpath("play-mvc"),让OpenRewrite自动从Maven仓库拉取依赖,确保依赖版本与测试代码中的Play版本(如2.7.x)一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:53:17