private static void loadAgent ( Config config , Log log , String agentJar , Class < ? > vmClass ) { try { // addAttach(config,log); // first obtain the PID of the currently-running process // ### this relies on the undocumented convention of the // RuntimeMXBean's // ### name starting with the PID, but there appears to be no other // ### way to obtain the current process' id, which we need for // ### the attach process RuntimeMXBean runtime = ManagementFactory . getRuntimeMXBean ( ) ; String pid = runtime . getName ( ) ; if ( pid . indexOf ( "@" ) != - 1 ) pid = pid . substring ( 0 , pid . indexOf ( "@" ) ) ; log . info ( "Instrumentation" , "pid:" + pid ) ; // JDK1.6: now attach to the current VM so we can deploy a new agent // ### this is a Sun JVM specific feature; other JVMs may offer // ### this feature, but in an implementation-dependent way Object vm = vmClass . getMethod ( "attach" , new Class < ? > [ ] { String . class } ) . invoke ( null , new Object [ ] { pid } ) ; // now deploy the actual agent, which will wind up calling // agentmain() vmClass . getMethod ( "loadAgent" , new Class [ ] { String . class } ) . invoke ( vm , new Object [ ] { agentJar } ) ; vmClass . getMethod ( "detach" , new Class [ ] { } ) . invoke ( vm , new Object [ ] { } ) ; } catch ( Throwable t ) { ExceptionUtil . rethrowIfNecessary ( t ) ; // Log the message from the exception. Don't log the entire // stack as this is expected when running on a JDK that doesn't // support the Attach API. log . log ( Log . LEVEL_INFO , "Instrumentation" , t ) ; } }
Attach and load an agent class .