question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proper way to repackage ByteBuddy into the library

See original GitHub issue

Some 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:

  1. Programmatic API using self-attach mechanism. Everything works fine, a user has our jar (and thus ByteBuddy) in the classpath.
  2. 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.jar we’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:open
  • Created 4 years ago
  • Reactions:1
  • Comments:14 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
elizarovcommented, Aug 2, 2019

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.

1reaction
raphwcommented, Jul 30, 2019

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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found