2009-03-18 17 views
5

Necesito obtener un seguimiento de pila para un proceso JVM que se ejecuta en un equipo cliente que usa Windows.Trazado de pila Java en Windows

El cliente tiene el JRE instalado pero no el JDK.

Quiero usar JStack pero no está instalado y no podemos instalar un JDK en la máquina del cliente. También traté de usar el producto de seguimiento de la pila AdaptJ de una sesión de Webstart de Java, pero eso no funcionó porque lo accedimos de forma remota y obtenemos el error de no ser la sesión que inició la aplicación en un PID especificado.

Básicamente, quiero una forma de instalar JStack sin instalar el JDK.

+3

Sólo como referencia, "matar -3 pid" hará un Linux jre/Unix para volcar todo el seguimiento de la pila hilo a la salida estándar. Muy, muy, muy útil. –

Respuesta

5

Probablemente desee utilizar SendSignal, que fue diseñado exactamente para este propósito.

+0

Al mirar la página web de SendSignal, tendría cuidado si la aplicación se ejecuta como un servicio (o si tiene -Xrs (reduce el uso de la señal)) como argumento. Si es así, el manejo ctrl + break de Java está deshabilitado y la aplicación terminará cuando reciba esta señal. –

+0

En realidad, uso SendSignal.exe para este propósito para provocar que un stackdump de un JRE se ejecute como un servicio. Esto funciona para mi. – Eddie

+0

Sí, si alguien ejecuta "java -Xrs ..." entonces quizás tenga un problema con SendSignal.exe. La solución es que no puedes hacer ambas cosas al mismo tiempo. Elige uno. Utilice -Xrs o use SendSignal.exe para generar un stackdump. Tu elección. – Eddie

2

¿Sería capaz de utilizar JConsole a través de acceso remoto?

+0

+1 jvisualvm también es útil –

4

El JDK y las herramientas asociadas funcionan bien ya sea que estén "instaladas" o no, si solo se cierra y se extrae en un directorio temporal, debería poder ejecutar jstack. (No son necesarias modificaciones PATH o JAVA_HOME). Solo asegúrese de utilizar la misma versión que corresponde al JRE con el que se ejecuta la aplicación. Al menos en el caso de JConsole, parece preocuparse si las versiones son diferentes. No estoy seguro de si jstack se comporta de la misma manera.

No estoy diciendo que esta sea la solución ideal, solo que funcionaría. Creo que las sugerencias de jdigital y Eddie son las mejores primeras apuestas, y aunque esto no debería interferir con una instalación java existente de la misma manera que lo haría el instalador, el cliente puede estar en desacuerdo independientemente.

2

jstack y jps son parte de tools.jar del JDK. También se requiere attach.dll para adjuntar jstack a un proceso.

Por supuesto, tools.jar y attach.dll no son parte de JRE.

Para hacer que jstack funcione en un sistema que no tiene JDK (principalmente Windows), suelo hacer lo siguiente.

  1. Copia tools.jar y attach.dll de JDK y ponen en alguna ubicación del sistema de destino. Ejemplo: a c: \ temp \ jstack
  2. Escriba un script bat para invocarlo manualmente usando JRE.

Por ejemplo, cree un archivo bat jstack.bat:

set JRE=c:\jrefolder 
"%JRE%\bin\java" -classpath "c:\temp\jstack\tools.jar" -Djava.library.path="c:\temp\jstack" sun.tools.jstack.JStack %* 

Del mismo modo para JPS, cree un jps.bat con contenido siguiente.

conjunto JRE = c: \ jrefolder

"%JRE%\bin\java" -classpath "c:\temp\jstack\tools.jar" -Djava.library.path="c:\temp\jstack" sun.tools.jps.Jps %* 

Uso:

jstack.bat -l <pid> 

Espero que esto ayude.

+0

jps funciona bien de esta manera, pero jstack falló con "java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider: Provider sun.tools.attach.WindowsAttachProvider no se pudo crear una instancia" –

+0

@EmmanuelBourg ¿Estás seguro de que attach.dll está presente en la ruta mencionada en -Djava.library.path =? Por favor confirma. Se requiere attach.dll para adjuntar el proceso a jstack. –

+0

Sí, pero estaba intentando adjuntarme a un proceso que se ejecuta como administrador, y mi shell no tenía privilegios elevados, lo que probablemente explica el problema. –

0

Para obtener un volcado de hilo con solo un JRE, necesita tools.jar y attach.dll del JDK de la misma versión de Java. Instala esto en alguna parte y copia esto en la jre. Debe ser una versión idéntica!

Si necesita un volcado de un proceso que se ejecuta bajo la cuenta del sistema, puede usar el sysinternals psexec.exe de Windows para obtener acceso al proceso. Copie esto en el contenedor de JRE o en algún lugar de la ruta.

Este archivo de proceso por lotes escribe el volcado de la pila en un archivo con un nombre de archivo de fecha y hora para que se puedan tomar y comparar fácilmente varios rastros.

Threads.bat

:: Creates a thread dump for the tomcat6.exe process 
:: saved in a timestamped filename and views it! 
:: Jim Birch 20111128 rev 2015-10-12 

::Required the following files to be placed in the jre/bin folder: 
:: attach.dll - From the Java JDK (must be the same version) 
:: tools.jar - ditto 
:: psexec.exe - from Windows sysinternals 

::cd to jre/bin 
d: 
cd \application\jre\bin 

::build datetime filename 
rem datetime from wmi.exe 
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set dt0=%%I 
rem datetime string as YYYY-MM-DD-hhmmss 
set dt=%dt0:~0,4%-%dt0:~4,2%-%dt0:~6,2%-%dt0:~8,6% 
set ff=td-%dt%.txt 
echo filename: %ff% 

::PID of the process by named exe, eg, tomcat6  
for /F "tokens=2" %%I in ('TASKLIST /NH /FI "IMAGENAME eq tomcat6.exe"') DO SET PID=%%I 
echo pid: %PID% 

::combine above with jstack command 
psexec -s jstack.exe -l %PID% >> %ff% 

:: view result 
start %ff% 

::insert pause to debug or timer to review script operation 
::ping localhost -n 20 >nul 
::pause