Search code examples
javabyte-buddy

Bytebuddy: apply a transform on an iterface based on name rather than class


I want to apply a transform on classes implementing a certain interface, but due to class loading issues I want to do it by name and not by providing the class. Is there a way to do that?

What I mean is that instead of:

new AgentBuilder.Default()
        .disableClassFormatChanges()
        .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
        .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
        .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
        .type(isSubTypeOf(myClass.class).and(not(isAbstract())).and(not(isInterface())))
        .transform(new AgentBuilder.Transformer.ForAdvice()
                .advice((ElementMatchers.named("method")),
                        "adviceClass"))
        .installOn(inst);

I want to do something like this (note the isSubTypeOf() below):

new AgentBuilder.Default()
        .disableClassFormatChanges()
        .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
        .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
        .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
        .type(isSubTypeOf(**TypeDescription.ForLoadedType.ofName(className)**).and(not(isAbstract())).and(not(isInterface())))
        .transform(new AgentBuilder.Transformer.ForAdvice()
                .advice((ElementMatchers.named("method")),
                        "adviceClass"))
        .installOn(inst);

Is there a way to do that?


Solution

  • There is a matcher for that: hasSuperType(named(className)). Alternatively, you can implement your own matcher and just navigate the type hierarchy. This can be slightly more efficient, for example if you know that the type in question is not an interface.