Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when trying to modify the response of a method assigned to a public static final config variable #1605

Open
jwalor opened this issue Mar 11, 2024 · 9 comments
Assignees
Labels
Milestone

Comments

@jwalor
Copy link

jwalor commented Mar 11, 2024

jdk corretto-17.0.7 , and bytebuddy version is 1.14.9

I get :

None of [public static java.lang.Object com.bcp.fraud.streams.Main$MyInterceptor.intercept(com.bcp.fraud.streams.Main$MyCallable,java.lang.Object[]) throws java.lang.Exception] allows for delegation from public static org.apache.kafka.common.config.ConfigDef io.confluent.kafka.schemaregistry.rest.SchemaRegistryConfig.baseSchemaRegistryConfigDef()

this is my code:

new AgentBuilder.Default()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.with(new FlowListener())
.ignore(nameStartsWith("net.bytebuddy."))
.type(ElementMatchers.named("io.confluent.kafka.schemaregistry.rest.SchemaRegistryConfig"))
.transform((builder, typeDescription, classLoader, module, protectionDomain) -> {
//return builder;
return builder
.method(named("baseSchemaRegistryConfigDef"))
.intercept(MethodDelegation.to(MyInterceptor.class));
})
.installOn(inst);

What I want is to modify a routine of that method in Java, what should I use?

I use net.bytebuddy.agent.ByteBuddyAgent.install method to instrumentation at runtime.

@raphw
Copy link
Owner

raphw commented Mar 13, 2024

What's your interceptor class, including annotations and imports?

@raphw raphw self-assigned this Mar 13, 2024
@raphw raphw added the question label Mar 13, 2024
@raphw raphw added this to the 1.14.1 milestone Mar 13, 2024
@jwalor
Copy link
Author

jwalor commented Mar 13, 2024

Hi , thanks for replying,
Is it technically possible to modify this method?
image

--> Code:
`import io.confluent.kafka.schemaregistry.rest.SchemaRegistryConfig;
import io.confluent.rest.RestConfigException;
import javassist.NotFoundException;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.MemberSubstitution;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;
import org.apache.kafka.common.config.ConfigDef;

import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import java.util.Properties;
import static net.bytebuddy.matcher.ElementMatchers.*;

public class MainX2 {

public static void main(String[] args) throws RestConfigException, NotFoundException {
    SchemaRegistryConfig test = new SchemaRegistryConfig(new Properties());
    Instrumentation instrumentation = ByteBuddyAgent.install();
    new AgentBuilder.Default()
            .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
            .with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
            .with(AgentBuilder.RedefinitionStrategy.Listener.StreamWriting.toSystemError())
            .with(AgentBuilder.Listener.StreamWriting.toSystemError().withTransformationsOnly())
            .with(AgentBuilder.InstallationListener.StreamWriting.toSystemError())
            .type(ElementMatchers.named("io.confluent.kafka.schemaregistry.rest.SchemaRegistryConfig"))
            .transform(new AgentBuilder.Transformer() {
                @Override
                public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription,
                                                        ClassLoader classLoader, JavaModule module, ProtectionDomain protectionDomain) {
                    try {
                        return builder
                                .visit(MemberSubstitution.strict()
                                        .method(named("baseSchemaRegistryConfigDef"))
                                        .replaceWith(MainX2.class.getMethod("baseSchemaRegistryConfigDef"))
                                        .on(any()));
                    } catch (NoSuchMethodException e) {
                        throw new RuntimeException(e);
                    }
                  
                }
            }).installOn(instrumentation);

    SchemaRegistryConfig teSchemaRegistryConfig = new SchemaRegistryConfig(new Properties());

    System.out.println(teSchemaRegistryConfig.baseSchemaRegistryConfigDef().configKeys().size());

}

public static ConfigDef baseSchemaRegistryConfigDef() {
    return new ConfigDef();
}

`
I would like to know if it is possible to replace the body of that method with a modified one. I have tried some examples but no success.

@raphw
Copy link
Owner

raphw commented Mar 13, 2024

It is, but the static initializer will not be rerun on a retransformation. In this case, you would need to hook before the class is loaded for the first time.

@jwalor
Copy link
Author

jwalor commented Mar 13, 2024

I agree Rafael, with AgentBuilder could I achieve it?
If you have any reference it would help me a lot for what I am looking for

@raphw
Copy link
Owner

raphw commented Mar 14, 2024

You mean rerun the static initializer? That is not possible, unfortunately, the JVM does not support it.

@jwalor
Copy link
Author

jwalor commented Mar 14, 2024

If I understood what you indicated... ("you would need to hook before the class is loaded for the first time.")
could you give me some reference on how I could resolve this case? thank you so much :)

@jwalor
Copy link
Author

jwalor commented Mar 15, 2024

@raphw
Could you just tell me which api to use?

@raphw
Copy link
Owner

raphw commented Mar 16, 2024

You are doing it right, but there's nothing that can fix your problem if the initializer already ran.

@jwalor
Copy link
Author

jwalor commented Mar 18, 2024

Thank you very much for the support! , I found everything about bytebuddy interesting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants