Proper way to repackage ByteBuddy into the library
See original GitHub issueSome context:
We at kotlinx.coroutines have a special “debug” library that uses ByteByddy to redefine some classes for the sake of better user experience.
Our API shape has two modes:
- Programmatic API using self-attach mechanism. Everything works fine, a user has our jar (and thus ByteBuddy) in the classpath.
- Attach mechanism. If a user already has its own application without our library in the classpath, we don’t want to force them to recompile their project.
So to make it as simple as
java -jar myapp.jar -javaagent:kotlinx-coroutines-debug.jarwe’ll have to shade ByteBuddy into our library. But then we can mess up with other libraries that use ByteBuddy, especially in case of incompatible versions. To avoid that, we not only shade but also repackage ByteBuddy.
It works fine most of the time but fails with java.lang.UnsatisfiedLinkError: Native Library /.../jre/lib/amd64/libattach.so already loaded in another classloader when the target application uses libraries that also use ByteBuddy (e.g. Spring or Mockito).
So the question is, what is the best way to have a self-contained JAR suitable for attach and that also works with other libraries that use ByteBuddy?
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:14 (8 by maintainers)
Top Results From Across the Web
Byte Buddy - runtime code generation for the Java virtual ...
Welcome, I'm your Byte Buddy! Byte Buddy is a code generation and manipulation library for creating and modifying Java classes during the runtime...
Read more >Java Code Manipulation with Byte Buddy - Sergio Martin Rubio
Byte Buddy is a library to help you create and modify Java classes and provides a feature for generating Java Agents.
Read more >ByteBuddy (Byte Buddy (without dependencies) 1.4.17 API)
Any rebased method is however inlined into the rebased type and any original code is preserved automatically. This way, the type's identity does...
Read more >Various ByteBuddy questions - Google Groups
Does ByteBuddy cache classes internally similar to the way that Cglib ... A problem Byte Buddy or any other ASM-using library faces in...
Read more >How to bundle a JAR file with its dependencies using maven
So far, in order for the agent to run smoothly, I need the ByteBuddy library .jar files to be present in the classpath...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

Thanks. JNA use is indeed safer. If we include it as a “plain” dependency, then there’s still a risk of a version conflict on JNA. However, if you use “separate classloader” trick, then it indeed works – JNA can be safely loaded from multiple classloaders 🎉 (I have not explicitly checked if it holds for the case of pre-main, but I don’t see how it should be different). Interestly, though, behind the scenes two JNA instances share one copy of the loaded native library, but create different proxies to it.
FYI: I extended Byte Buddy agent such that it is now possible to attach to a VM without using the JDK-specific tools.jar. I simply reimplemented the attach API for OpenJ9/HotSpot on Solaris/Windows/POSIX which is now a part of Byte Buddy.
All you need to do is to include JNA for this. Note however that JNA is not shadable due to its use of JNI.
However, this mechanism is not vulnerable to being loaded by multiple class loaders. Maybe instead of shading you can isolate Byte Buddy agent and JNA in a seperate class loader and work around that way? Due to the possibility of using Byte Buddy agent in a premain state, it is not trivial to work around the shading, unfortunately but I will investigate further.
As a bonus, with the JNA-based solution, you can self-attach on non-JDK VMs if this is relevant to you.