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

ByteBuddy报错:无法定位类中name字段,请求社区协助排查

问题排查:ByteBuddy Advice中无法找到name字段的异常

我正在探索ByteBuddy库,尝试为方法创建Advice,但运行时抛出java.lang.IllegalStateException异常,提示无法找到org.purbarun.proxy.MyService$ByteBuddy$8XL9Iy3U类中的name字段。以下是异常信息和测试代码,请求帮忙排查错误。

异常信息

Exception in thread "main" java.lang.IllegalStateException: Cannot locate field named name for class org.purbarun.proxy.MyService$ByteBuddy$8XL9Iy3U
    at net.bytebuddy.asm.Advice$OffsetMapping$ForField$Unresolved.resolve(Advice.java:2534)
    at net.bytebuddy.asm.Advice$OffsetMapping$ForField.resolve(Advice.java:2459)
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$ForMethodEnter.doApply(Advice.java:9979)
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$ForMethodEnter$WithDiscardedEnterType.doApply(Advice.java:10081)
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$ForMethodEnter.apply(Advice.java:9937)
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$AdviceMethodInliner.visitMethod(Advice.java:9620)
    at net.bytebuddy.jar.asm.ClassReader.readMethod(ClassReader.java:1354)
    at net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:745)
    at net.bytebuddy.utility.AsmClassReader$ForAsm.accept(AsmClassReader.java:225)
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$AdviceMethodInliner.apply(Advice.java:9613)
    at net.bytebuddy.asm.Advice$AdviceVisitor.onAfterExceptionTable(Advice.java:11919)
    at net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.considerEndOfExceptionTable(ExceptionTableSensitiveMethodVisitor.java:49)
    at net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.visitVarInsn(ExceptionTableSensitiveMethodVisitor.java:113)
    at net.bytebuddy.implementation.bytecode.member.MethodVariableAccess$OffsetLoading.apply(MethodVariableAccess.java:354)
    at net.bytebuddy.implementation.bytecode.StackManipulation$Compound.apply(StackManipulation.java:243)
    at net.bytebuddy.implementation.SuperMethodCall$Appender.apply(SuperMethodCall.java:139)
    at net.bytebuddy.asm.Advice$Appender$EmulatingMethodVisitor.resolve(Advice.java:12525)
    at net.bytebuddy.asm.Advice$Appender.apply(Advice.java:12478)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:732)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:717)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:624)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:6072)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2246)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$UsingTypeWriter.make(DynamicType.java:4085)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3769)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:4021)
    at org.purbarun.proxy.MainRunner.main(MainRunner.java:14)

测试代码

public class MyService {
    public void myMethod(String args) {
        System.out.println(args);
    }
}

public class MyServiceInterceptor {
    @OnMethodEnter
    static void enter(@This Object thisObject,
            @Origin String origin,
            @Origin("#t #m") String detaildOrigin,
            @AllArguments Object[] ary,
            @FieldValue(value = "name", readOnly = false) String nameField){
        System.out.println("test");
    }
}

public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException, IllegalArgumentException {
        Class<? extends MyService> type=new ByteBuddy()
          .subclass(MyService.class)
          .method(ElementMatchers.isMethod()).intercept(Advice.to(MyServiceInterceptor.class))
          .make()
          .load(MyService.class.getClassLoader())
          .getLoaded();
        
        String returnVal = (String)type.getDeclaredMethod("myMethod", String.class).invoke(type.getDeclaredConstructor().newInstance(), "Method");
        System.out.println("return value: " + returnVal);
    }

问题原因和解决方案

核心问题

MyService类中不存在name字段,但拦截器方法enter中使用@FieldValue("name")尝试获取该字段,ByteBuddy在生成代理类时无法找到对应字段,因此抛出异常。

解决方案

方案1:添加需要的字段(如果确实需要操作name字段)

在MyService类中添加name字段:

public class MyService {
    private String name; // 添加name字段
    public void myMethod(String args) {
        System.out.println(args);
    }
}

方案2:移除无用的字段参数(如果不需要操作name字段)

删除拦截器中@FieldValue相关的参数:

public class MyServiceInterceptor {
    @OnMethodEnter
    static void enter(@This Object thisObject,
            @Origin String origin,
            @Origin("#t #m") String detaildOrigin,
            @AllArguments Object[] ary){
        System.out.println("test");
    }
}

额外修正点

myMethod是void返回类型,但main方法中强制将返回值转为String,会触发ClassCastException,需要修正main方法:

public static void main(String[] args) throws Exception {
    Class<? extends MyService> type = new ByteBuddy()
            .subclass(MyService.class)
            .method(ElementMatchers.isMethod()).intercept(Advice.to(MyServiceInterceptor.class))
            .make()
            .load(MyService.class.getClassLoader())
            .getLoaded();
    
    // void方法无需接收返回值
    type.getDeclaredMethod("myMethod", String.class)
        .invoke(type.getDeclaredConstructor().newInstance(), "Method");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:37:32