2009-08-14 14 views
22

¿Es posible insertar un javaagent después del inicio de la máquina virtual desde la misma máquina virtual?Iniciar un agente de Java después del inicio del programa

Digamos, por ejemplo, que tenemos un agente en un contenedor myagent.jar con la configuración de metadatos adecuada y un método agentmain ya implementado. Ahora el programa de los usuarios llama a una llamada de API que debería resultar en la inserción del agente para que pueda redefinir las clases.

¿Se puede hacer y cómo?

Respuesta

4

Usted debe ser capaz de hacerlo en Java 6, vea los "Agentes de arrancar Después virtual de inicio" package documentation capítulo

edición: Tal vez era posible en Java 5 y ya sólo los javadocs no mencionan que explícitamente

+0

Sin embargo, no especifica cuál es la llamada al método. Sin embargo, si miramos más adentro ((URLClassLoader) ClassLoader.getSystemClassLoader()). AddURL (....) ¿dónde la URL agregada apuntó al resultado myagent.jar en el que se llama al agente principal? –

+0

¿Es este Java 6 en general o solo con HotSpot? –

+0

@Paul: No lo he probado, así que no puedo decir si funciona así, pero parece razonable. Sin embargo, tendrá que llamar a addURL por reflexión ya que está protegido. Algo así como: URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); \t Clase sysclass = URLClassLoader.class; \t try { \t \t Método method = sysclass.getDeclaredMethod ("addURL", parámetros); \t \t method.setAccessible (true); \t \t method.invoke (sysloader, new Object [] {yourURL}); \t} – HerdplattenToni

18

https://web.archive.org/web/20141014195801/http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/ tiene un excelente ejemplo de cómo escribir un agente y cómo iniciarlo sobre la marcha.

+3

El ejemplo vinculado está incompleto y no funciona. –

+3

No está destinado a ser un tutorial independiente, cierto. Pero es un gran ejemplo para los desarrolladores avanzados de Java. Yo, personalmente, no tuve ningún problema con el ejemplo. –

+1

El enlace está roto. Pude encontrarlo archivado en WayBackMachine: https://web.archive.org/web/20141014195801/http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with -javaagents/ – 11101101b

12

Sí, solo tiene que pasar el ID del proceso de JVM al método VirtualMachine.attach(String pid) y cargar el contenedor del agente. La clase VirtualMachine está disponible en el archivo JDK_HOME/lib/tools.jar. Aquí hay un ejemplo de cómo activo un agente en tiempo de ejecución:

public static void attachGivenAgentToThisVM(String pathToAgentJar) { 
    try {                    
    String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();             
    String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@'));             
    VirtualMachine vm = VirtualMachine.attach(pid);                    
    vm.loadAgent(pathToAgentJar, ""); 
    vm.detach(); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    } 
}                            
+0

gracias por una buena respuesta. pero cuando intento lo mismo, obtengo una excepción ** com.sun.tools.attach.AgentLoadException: agente JAR no encontrado o ningún atributo de clase de agente ** – madhu

+1

Sospecho que es un problema de dependencia, aquí cómo resolverlo en maven : http://m.blog.csdn.net/blog/chendeng8899/8487336 (sección "Carga dinámica de un javaagent en tiempo de ejecución") – pierpytom

Cuestiones relacionadas