You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Fabric环境下Mixin注入Lambda内部方法的method与at参数配置问题

Fabric环境下Mixin注入Lambda内部方法的method与at参数配置问题

问题回顾

你现在在给Minecraft Fabric模组编写Mixin,想要注入到Foo.bar()方法里Lambda内部的System.out.println调用之后,但遇到了Mixin找不到目标lambda方法、注入点解析失败的问题,报错提示InvalidInjectionException,同时抛出了方法找不到的错误。

核心错误点分析

从你的代码和报错堆栈来看,主要有两个关键错误:

  1. Lambda方法的签名格式错误:你写的lambda$bar$0(;)V不符合Java方法描述符规则,无参方法的正确描述符应该是()V(括号内为空,分号是参数列表与返回值的分隔符,无参时括号内不需要额外加冒号)。
  2. 注入点的Target方法描述不完整:你配置的Ljava/io/PrintStream;println(Ljava/lang/String)缺少了方法的返回值描述,完整的方法签名必须补全;)V,表示返回值为void。

正确的Mixin配置方案

下面是修正后的完整Mixin代码,我会逐行解释关键参数的调整:

@Mixin(Foo.class)
public abstract class FooMixin {
    // 修正method参数:使用符合规则的lambda方法签名
    @Inject(
            method = "lambda$bar$0()V", 
            at = @At(
                    value = "INVOKE", 
                    // 修正target:补全完整的方法描述符
                    target = "Ljava/io/PrintStream;println(Ljava/lang/String;)V",
                    shift = At.Shift.AFTER
            )
    )
    public void doSomething(CallbackInfo ci) {
        System.out.println("The mixin has succeeded");
    }
}

关键参数详细说明

  • method参数:"lambda$bar$0()V"

    • 这是Java编译器对lambda的固定命名规则:lambda$原方法名$lambda编号,这里bar是原方法名,0是当前方法内第一个lambda的编号(从0开始递增,多个lambda会依次编号)。
    • 末尾的()V是方法描述符:()表示方法无参数,V表示返回值为void,必须和字节码中生成的lambda方法完全匹配。
  • at参数的target:"Ljava/io/PrintStream;println(Ljava/lang/String;)V"

    • 这是System.out.println(String)的完整方法签名:
      • Ljava/io/PrintStream; 是方法所属类的全限定名
      • println 是目标方法名
      • (Ljava/lang/String;) 是参数列表(一个String类型参数)
      • V 是返回值类型(void)
    • 完整的描述符是Mixin解析注入点的必要条件,缺任何部分都会导致注入点验证失败。

额外验证小技巧

如果还是遇到方法找不到的问题,你可以用字节码查看工具(比如Bytecode Viewer、JD-GUI的字节码视图)打开编译后的Foo.class,确认lambda生成的方法的准确名称和签名:

  • 它会显示为private static void lambda$bar$0()(因为原方法bar是静态的,所以lambda方法也是静态的)
  • 对应的方法描述符就是()V

报错根源总结

  • 错误的method签名让Mixin无法定位到目标lambda生成的方法,触发“找不到方法”的底层错误。
  • 不完整的target方法描述符,让Mixin的注入点解析器(BeforeInvoke)无法识别目标调用,直接抛出InvalidInjectionException——这就是你看到的堆栈跟踪的核心原因。

按照上面的配置修改后,Mixin应该就能成功注入到lambda内部的println调用之后了,快去测试一下吧~

火山引擎 最新活动