Replies: 5 comments 6 replies
-
I think you are right. I have observed that if two agents attempt to attach to the same JVM from two different class loaders, some VMs hang forever when the second class loader attempts to load the native library that is included with the JVM. This problem was very visible on JDK version 8 but I have not seen it in a while, but I am not using MacOS. One way to avoid it was to use the emulation natives where the problem did not occur. Another way of doing it was to inject the |
Beta Was this translation helpful? Give feedback.
-
Indeed. In this case, try setting you Instrumentation instance to the instrumentation field of the Installer class. This will trigger Byte Buddy no longer trying to attach but reusing the instance. This requires no update. If you use reflection, you can abort this if Byte Buddy is not present on the class path. |
Beta Was this translation helpful? Give feedback.
-
@raphw Hello,
In my agent I don't even have dependency on byte-buddy-agent jar, only byte-buddy. what i found is the following behavior, i understand what's happening but i don't understand why. while my agent is added in command line with -javaagent : if the application loads by a different class loader, for example i tested a spring boot app running with java -jar, So I think the problem is only when my agent ,which always loads on system class loader, installs a bytebuddy transformer, and the application is also loaded on system class loader and calls ByteBuddyAgent.install(), only then the process hangs and the above trick solves it. I don't understand why it behaves like that, and I don't understand why if i don't relocate bytebuddy packages in my agent there is no problem. but I tested the above again and again and its very consistent. if you have more suggestion I'll be happy to hear. Thank you very much for your help! |
Beta Was this translation helpful? Give feedback.
-
With the changes in Byte Buddy, Byte Buddy would now also discover the class from a shaded location, so your work around will be more robust. You just have to make sure to initialize this common dispatcher. Of course, if another library also does a self-attach, you would need to "preload" that library, too, otherwise you'd run into the same problem. |
Beta Was this translation helpful? Give feedback.
-
I encountered this issue of the external ByteBuddy agent install hanging with a Mockito test in one of my projects. Interestingly enough the issue is 100% reproducible on Azul Zulu OpenJDK 17.0.12, but on Azul Zulu OpenJDK 21.0.4 there is no issue. I've decided to not investigate this further, because this particular project will be abandoned within a month, but I thought it might be an interesting data point. |
Beta Was this translation helpful? Give feedback.
-
Hello,
We have an issue related to bytebuddy that happens in very specific conditions.probably related to relocating bytebuddy packages in a shaded jar.
for context , it is all part of digma-ai intellij plugin
We have a java agent that uses bytebuddy to inject annotations to specific methods based on predefined criteria. we inject opentelemetry WithSpan and another marker annotation.
this is the transformer code:
The transformer uses a long list of type and method matchers.
The agent is packaged as shaded jar using gradle shadow plugin and relocates bytebuddy packages
relocate("net.bytebuddy", "org.digma.net.bytebuddy")
the agent also uses opentelemetry-javaagent-extension-api because it has some useful matchers and relocates that too
relocate("io.opentelemetry", "org.digma.io.opentelemetry")
on startup the agent checks if opentelemetry WithSpan is available in system class loader and if not injects the opetelemetry api to system classloader search using instrumentation.appendToSystemClassLoaderSearch
it adds the following jars:
opentelemetry-api-1.35.0.jar
opentelemetry-context-1.35.0.jar
opentelemetry-instrumentation-annotations-2.1.0.jar
we add the agent to application with JAVA_TOOL_OPTIONS together with opentelemetry java agent, something like that:
JAVA_TOOL_OPTIONS="-javaagent:/tmp/digma-agent.jar -javaagent:/tmp/opentelemetry-javaagent.jar -Dotel.javaagent.extensions=/tmp/digma-otel-agent-extension.jar -Dotel.exporter.otlp.traces.endpoint=https://localhost:5051 -Dotel.service.name=spring-petclinic.test -Dotel.traces.exporter=otlp -Dotel.exporter.otlp.protocol=grpc "
It all works well most of the time. but if the application tries to install a bytebuddy agent by calling ByteBuddyAgent.install the process hangs forever. one example is a unit test with mockito.
ByteBuddyAgent.installExternal tries to start an attache process and waits forever, looks like the process can not start but never fails.
this is a part of thread dump:
Now, and this is the weird part, it happens only on certain conditions, and we manage to make it work in these condition by adding some vmoptions.
we've tested these condition again and again by different people and its 100% consistent.
with the above condition we manage to make it work by doing any of the following:
the condition look weird to me, and i couldn't get to the cause of the issue, we have many mac users with jdk 17 and that will effect many of our users.
I have a feeling that the relocated bytebuddy packages is the cause but i'm not sure because we manage to make it work by adding Xmx or by not adding jars to system class loader search.
I know that opentelemetry java agent also uses relocated bytebuddy packages but i still didn't figure out how they do it, they do something not standard. but IMO just relocation with gradle shadow plugin should work, and it works until the application tries to install a bytebuddy agent using attache api.
maybe someone has an idea ?
maybe @raphw ?
Beta Was this translation helpful? Give feedback.
All reactions