raphw / byte-buddy

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

Question: How to add some parameters in ByteBuddy starting process when using ByteBuddy dependency #1624

Closed steverao closed 6 days ago

steverao commented 5 months ago

I encountered a problem when using ByteBuddy by jar. I add following dependencies:

<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy</artifactId>
    <version>1.11.22</version>
</dependency>
<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy-agent</artifactId>
    <version>1.11.22</version>
</dependency>

And using following codes to instrument some specific classes in my app:

Instrumentation install = ByteBuddyAgent.install();
    new AgentBuilder.Default()
        .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
        .with(AgentBuilder.PoolStrategy.Default.EXTENDED)
        .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
        .with(new Listener())
        .type(named("xxxx"))
        .transform(new Transformer())
        .installOn(install);

In the running environment, I will set environment variable of JAVA_TOOL_OPTIONS="-javaagent:A.jar -javaagent:B.jar" for my application. It's very necessary for me to do it. For some reasons, I won’t go into details. But I found at beginning phase of application, besides app's process, there is a ByteBuddy process like: image Because of JAVA_TOOL_OPTIONS="-javaagent:A.jar -javaagent:B.jar", it will start with two Java Agent. they will cause the process of ByteBuddy can't finish task normally and cause my main thread will also be blocked:

"main" #1 prio=5 os_prio=31 cpu=2460.44ms elapsed=70.62s tid=0x00007feba600d200 nid=0x2003 in Object.wait()  [0x000070000fc1d000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(java.base@17.0.6/Native Method)
    - waiting on <no object reference available>
    at java.lang.Object.wait(java.base@17.0.6/Object.java:338)
    at java.lang.ProcessImpl.waitFor(java.base@17.0.6/ProcessImpl.java:434)
    - locked <0x000000070342be78> (a java.lang.ProcessImpl)
    at net.bytebuddy.agent.ByteBuddyAgent.installExternal(ByteBuddyAgent.java:694)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:626)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:606)
    - locked <0x000000070342bf40> (a java.lang.Class for net.bytebuddy.agent.ByteBuddyAgent)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:558)
    at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:535)
    at com.example.demo.bytebuddy.FeignOkHttpHeaderEnhance.init(FeignOkHttpHeaderEnhance.java:32)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@17.0.6/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@17.0.6/NativeMethodAccessorImpl.java:77)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@17.0.6/DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(java.base@17.0.6/Method.java:568)
    ......

I debug the it and found the core problem is that there is a conflict when the ByteBuddy process mounts Java Agent A and B. I wonder if there is a way to add the JAVA_TOOL_OPTIONS="" parameter to the ByteBuddy startup process in the code to solve this problem?

raphw commented 5 months ago

Could you try with the latest version of Byte Buddy? I do not support older releases.

steverao commented 5 months ago

Could you try with the latest version of Byte Buddy? I do not support older releases.

I searched source code of 1.14.14:

private static void install(AttachmentProvider attachmentProvider, String processId, String argument, AgentProvider agentProvider, boolean isNative) {
......
}

protected interface AgentProvider {
......
}

Because, the parameter of AgentProvider is protected, so it seems can't be invoked in personal application directly.

raphw commented 5 months ago

Not sure how this relates? Why are you attaching if you already specify the agent?