/** * Installs a Java agent using the Java attach API. This API is available under different access * routes for different JVMs and JVM versions or it might not be available at all. If a Java agent * cannot be installed by using the supplied attachment provider, a {@link IllegalStateException} * is thrown. * * @param attachmentProvider The attachment provider to use for the installation. * @return An instrumentation instance representing the currently running JVM. */ public static synchronized Instrumentation install(AttachmentProvider attachmentProvider) { Instrumentation instrumentation = doGetInstrumentation(); if (instrumentation != null) { return instrumentation; } AttachmentProvider.Accessor accessor = attachmentProvider.attempt(); if (accessor.isAvailable()) { try { doInstall(accessor); } catch (Exception exception) { throw new IllegalStateException( "Error during attachment using: " + attachmentProvider, exception); } return getInstrumentation(); } else { throw new IllegalStateException( "This JVM does not support attachment using: " + attachmentProvider); } }
/** * Performs the actual installation of the Byte Buddy agent. * * @param accessor An available accessor for accessing the Java attachment API. * @throws Exception If the installation is not possible. */ private static void doInstall(AttachmentProvider.Accessor accessor) throws Exception { Class<?> virtualMachine = accessor.getVirtualMachineType(); Object virtualMachineInstance = virtualMachine .getDeclaredMethod(ATTACH_METHOD_NAME, String.class) .invoke(STATIC_MEMBER, accessor.getProcessId()); File agentJar = File.createTempFile(AGENT_FILE_NAME, JAR_FILE_EXTENSION); try { saveAgentJar(agentJar); virtualMachine .getDeclaredMethod(LOAD_AGENT_METHOD_NAME, String.class, String.class) .invoke(virtualMachineInstance, agentJar.getAbsolutePath(), WITHOUT_ARGUMENTS); } finally { try { virtualMachine.getDeclaredMethod(DETACH_METHOD_NAME).invoke(virtualMachineInstance); } finally { if (!agentJar.delete()) { Logger.getAnonymousLogger().info("Cannot delete temporary file: " + agentJar); } } } }