如何在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
相关产品推荐
相关产品推荐

