Last active
March 7, 2024 06:14
-
-
Save wu-sheng/101667979034e019c451ebb7e481d9a6 to your computer and use it in GitHub Desktop.
byte-buddy appendToBootstrapClassLoaderSearch, and jdk instrumentation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* All codes from stagemonitor apm, which gives a example about how to use instrumentation::appendToBootstrapClassLoaderSearch | |
* This will be very useful for instrument some class in rt.jar | |
*/ | |
private static boolean initInstrumentation() { | |
try { | |
/** | |
* this try-catch block shows two ways about instrumentation. | |
* ref issue: https://github.com/raphw/byte-buddy/issues/237 | |
*/ | |
try { | |
instrumentation = ByteBuddyAgent.getInstrumentation(); | |
} catch (IllegalStateException e) { | |
instrumentation = ByteBuddyAgent.install( | |
new ByteBuddyAgent.AttachmentProvider.Compound( | |
new EhCacheAttachmentProvider(), | |
ByteBuddyAgent.AttachmentProvider.DEFAULT)); | |
} | |
ensureDispatcherIsAppendedToBootstrapClasspath(instrumentation); | |
if (!Dispatcher.getValues().containsKey(IGNORED_CLASSLOADERS_KEY)) { | |
Dispatcher.put(IGNORED_CLASSLOADERS_KEY, Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>())); | |
} | |
hashCodesOfClassLoadersToIgnore = Dispatcher.get(IGNORED_CLASSLOADERS_KEY); | |
return true; | |
} catch (Exception e) { | |
logger.warn("Failed to perform runtime attachment of the stagemonitor agent. Make sure that you run your " + | |
"application with a JDK (not a JRE)." + | |
"To make stagemonitor work with a JRE, you have to add the following command line argument to the " + | |
"start of the JVM: -javaagent:/path/to/byte-buddy-agent-<version>.jar", e); | |
return false; | |
} | |
} | |
private static void ensureDispatcherIsAppendedToBootstrapClasspath(Instrumentation instrumentation) | |
throws ClassNotFoundException, IOException { | |
final ClassLoader bootstrapClassloader = ClassLoader.getSystemClassLoader().getParent(); | |
try { | |
bootstrapClassloader.loadClass(DISPATCHER_CLASS_NAME); | |
// already injected | |
} catch (ClassNotFoundException e) { | |
final JarFile jarfile = new JarFile(createTempDispatcherJar()); | |
instrumentation.appendToBootstrapClassLoaderSearch(jarfile); | |
bootstrapClassloader.loadClass(DISPATCHER_CLASS_NAME); | |
} | |
} | |
private static File createTempDispatcherJar() throws IOException { | |
final InputStream input = AgentAttacher.class.getClassLoader() | |
.getResourceAsStream("stagemonitor-dispatcher.jar.gradlePleaseDontExtract"); | |
if (input == null) { | |
throw new IllegalStateException("If you see this exception inside you IDE, you have to execute gradle " + | |
"processResources before running the tests."); | |
} | |
final File tempDispatcherJar = File.createTempFile("stagemonitor-dispatcher", ".jar"); | |
tempDispatcherJar.deleteOnExit(); | |
IOUtils.copy(input, new FileOutputStream(tempDispatcherJar)); | |
return tempDispatcherJar; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment