raphw / byte-buddy

Runtime code generation for the Java virtual machine.
https://bytebuddy.net
Apache License 2.0
6.28k stars 807 forks source link

Add static method to class not working #1465

Closed beikov closed 1 month ago

beikov commented 1 year ago

Hi there, I'm trying to add a static method to a newly created class but there seem to be method filters in place that prevent non-virtual methods to be compiled. This is how I create the method:

builder = builder.defineMethod(
    "get_" + getter.getName(),
    TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(
        getterType
    ),
    Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
)
.withParameter( clazz )
.intercept(new Implementation.Simple(new GetFieldOnArgument(getter)));

net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.InstrumentableMatcher#resolve and net.bytebuddy.dynamic.scaffold.MethodGraph.Compiler.Default#compile both create matchers that only handle methods which are virtual.

How am I supposed to add a static method to a class that I want to create?

raphw commented 1 year ago

I cannot reproduce this problem. Can you create an executable sample?

beikov commented 1 year ago

Turns out, one of the parameters of the method was not visible to the class in which I wanted to define the method: bytebuddy-1465.zip

You are apparently filtering out methods with instrumentedType.getDeclaredMethods().filter(not(isVirtual()).and(relevanceMatcher)) in net.bytebuddy.dynamic.scaffold.MethodRegistry.Default#prepare, and the relevanceMatcher seems to consider visibility. Wouldn't it be better to throw an error instead?

raphw commented 1 year ago

Those methods do sometimes exist for bridging calls with respect to generics. But it should indeed be more explicit if you define such methods explicitly. I will have a look if this can be improved.