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

如何在OpenRewrite中排除类/方法不被Recipe替换?Java17升级测试失败

如何在OpenRewrite中排除特定类/方法避免被Recipe修改?

针对你遇到的Collections.singletonMap被UpgradeToJava17 Recipe替换为Map.of导致测试失败的问题,有三种实用方案可以解决:

1. 通过配置文件指定排除规则

在项目根目录的rewrite.yml中自定义Recipe,基于原UpgradeToJava17添加排除条件,精准跳过特定类或方法的修改:

示例配置:排除指定测试类

type: specs.openrewrite.org/v1beta/recipe
name: com.example.CustomJava17Upgrade
displayName: 带排除规则的Java17升级
recipeList:
  - org.openrewrite.java.migrate.UpgradeToJava17:
      exclude:
        # 跳过整个测试类的修改
        - com.example.MyNullKeyMapTest
        # 或者跳过类下所有方法
        - com.example.MyNullKeyMapTest.*

示例配置:仅排除特定方法调用

如果需要更精细控制,可通过匹配方法签名排除Collections.singletonMap的替换:

type: specs.openrewrite.org/v1beta/recipe
name: com.example.CustomJava17Upgrade
displayName: 带排除规则的Java17升级
recipeList:
  - org.openrewrite.java.migrate.UpgradeToJava17:
      exclude:
        - java.util.Collections.singletonMap(..)

2. 使用@SuppressWarnings注解局部跳过

在需要保留原代码的方法或类上添加@SuppressWarnings("openrewrite"),OpenRewrite会自动跳过对该元素的所有修改:

@SuppressWarnings("openrewrite")
@Test
void testNullKeyMap() {
    // 此方法内的Collections.singletonMap不会被替换
    Map<String, Object> map = Collections.singletonMap(null, "test-value");
    // 测试逻辑
}

3. 自定义Recipe覆盖默认行为

如果需要复杂的判断逻辑(比如仅当存在null键时跳过替换),可以继承原UpgradeToJava17 Recipe,修改其替换逻辑:

public class CustomUpgradeToJava17 extends UpgradeToJava17 {
    @Override
    public TreeVisitor<?, ExecutionContext> getVisitor() {
        TreeVisitor<?, ExecutionContext> baseVisitor = super.getVisitor();
        return new TreeVisitor<Tree, ExecutionContext>() {
            @Override
            public Tree visit(Tree tree, ExecutionContext ctx) {
                if (tree instanceof MethodInvocation mi) {
                    // 判断是否为Collections.singletonMap调用,且第一个参数是null字面量
                    boolean isSingletonMapCall = mi.getMethodType().getDeclaringType().getFullyQualifiedName().equals("java.util.Collections")
                            && mi.getMethodName().equals("singletonMap");
                    boolean hasNullKey = mi.getArguments().get(0) instanceof NullLiteral;
                    
                    if (isSingletonMapCall && hasNullKey) {
                        return tree; // 跳过替换
                    }
                }
                return baseVisitor.visit(tree, ctx);
            }
        };
    }
}

之后在rewrite.yml中使用这个自定义Recipe即可:

type: specs.openrewrite.org/v1beta/recipe
name: com.example.CustomUpgradeToJava17
displayName: 带null键判断的Java17升级
recipeList:
  - com.example.CustomUpgradeToJava17

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:15:09