2009-07-29 15 views
13

Con frecuencia muestro las herramientas jhat, jps y jstack establecidas para desarrolladores en Linux y Mac. Sin embargo, un desarrollador indicó recientemente que estos no se pueden usar en Windows si la aplicación Java en cuestión se ejecuta como Windows Service.No se pueden depurar los servicios de Windows de Java con jhat, jps, jstack

A Sun-filed bug says something very similar, pero se cerró debido a inactividad.

He probado esto por mí mismo, y de hecho parece ser cierto, aunque no puedo creerlo. Aquí está la disposición:

  1. Tomcat o similares de carreras como un servicio de Windows con el "Iniciar sesión como" == "sistema local"
  2. Un usuario con privilegios de administrador e ingresados ​​a la misma máquina Windows.
  3. El administrador abre el Administrador de tareas de Windows, puede ver que java.exe ejecuta
  4. El administrador abre la consola, escribe "jps", recupera una lista de procesos que no incluye el proceso de servicio java de Tomcat.
  5. Como intento de fuerza bruta, obtenga el PID de tomcat como un servicio del Administrador de tareas de Windows. Escriba jstack < pid>. Obtenga una respuesta: < pid> ningún proceso

Esto parece reproducible en Windows XP, Windows 2003 Server y Windows 7. Las versiones de Java 1.5 y 1.6 producen el mismo resultado.

¿Hay alguna manera desde la terminal, aunque haya iniciado sesión como administrador, de "sudoear" para obtener JPS y las otras herramientas para ver el servicio de Java?

+0

¿Ha intentado (o es una opción) conectarse usando las opciones de administración remota en lugar de un PID? – McDowell

+0

Es posible que tengamos que recurrir a eso, configurar un jstatd en el ejecutor del servicio para exponer el proceso de Java en un socket, pero el objetivo era simplemente hacerlo a través de PID. Solo quiero confirmar que no me estoy perdiendo nada aquí. Esto parece un gran obstáculo con Windows pero no es un problema en Mac/BSD/Linux. –

+0

¿Resolvió esto la respuesta de Devon_C_Miller? Ejecuto jconsole como SYSTEM, pero esto no eliminó el problema (ver mi comentario sobre la respuesta de Devon_C_Miller) – ripper234

Respuesta

1

Solo obtiene los procesos que "le pertenecen": la misma identificación de usuario.

¿Se puede conectar a él con jvisualvm?

+0

No se puede acceder a los procesos con jvisualvm tampoco. Aparentemente jps y jvisualvm usan la lib/api subyacente idéntica para su interrogación (jvmstat) –

4

que he tenido procesos de depuración suerte ejecutados por el usuario del sistema ejecutando esto desde un símbolo del sistema:

c:> time/t 
11:18 AM 
c:> at 11:19 /interactive cmd.exe 
Added a new job with job ID = 1 

Use un minuto de tiempo 1 en el futuro. Cuando se ejecuta el trabajo "at", se abre un comando de comando de Windows en ejecución como el SISTEMA del usuario. Desde allí, debería poder ver los procesos de java.

Si el servicio se ejecuta como un usuario local (verifique los detalles de "mmc% windir% \ system32 \ SERVICES.MSC" haciendo doble clic en el servicio y seleccionando la pestaña "Iniciar sesión") puede hacer lo mismo lo usando "runas":

runas /user:USERNAME cmd.exe 
+0

+1 Wicked, me encanta :) –

+0

Consulte esta pregunta relacionada: http://stackoverflow.com/questions/77528/how-do-you -run-cmd-exe-under-the-local-system-account – ripper234

+0

Sé ver los servicios en jconsole, pero no puedo conectarme a ellos (están atenuados). Cuando intento conectarme manualmente al puerto, no puedo. CurrPorts muestra que el puerto correcto es definitivamente escuchado por la JVM. – ripper234

8

Para ejecutar las utilidades, puede conectarse a la sesión de la Consola usando "mstsc/admin" usando una cuenta de inicio de sesión (no estoy seguro de los permisos exactos que necesita tener, el mío estaba en el grupo Administradores) y use Sysinternals psexec herramienta para ejecutar como sistema. Aquí hay un ejemplo del uso de jstack.exe:

psexec -s "%JAVA_HOME%\bin\jstack.exe" PID >stack.txt
Donde PID es el ID de proceso de su proceso. También puede tener que sustituir la ruta real a su JDK dependiendo de su entorno específico.

Además, el TEMP directory must be set correctly o una vez más las herramientas no funcionarán.

0

Este es mi archivo por lotes para grabar un hilo de volcado

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

::Note this required the following files to be placed in the confluence jre/bin folder: 
:: 
:: attach.dll - From the Java JDK (must be the same version) 
:: tools.jar - ditto 
:: psexec.exe - from Windows sysinternals 
:: Also, the TEMP directory must be set (stack overflow) 
set TEMP=c:\windows\temp 

::go to run location 
d: 
cd \confluence.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% 

::tomcat PID 
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 (won't work without psexec) 
psexec -s "D:\confluence.application\jre\bin\jstack.exe" -l %PID% >> %ff% 

:: view output txt file 
start %ff% 

::pause to review script operation, or use ping to wait a few secs 
::ping localhost -n 20 >nul 
pause 
0

Aquí está la solución que finalmente funcionó para mí para obtener stacktraces del proceso de java sin preparación que corre bajo un usuario diferente en la sesión de terminal o como servicio de Windows.

jstack.cmd:

@FOR /F "usebackq tokens=2" %%I in (`TASKLIST /NH /FI "imagename eq tomcat.exe" /FI "username eq SYSTEM"`) DO set PID=%%I 
PsExec.exe -h -s -i cmd /c jstack.exe -F %PID% ^>%~dp0jstack_%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%__%TIME:~0,2%_%TIME:~3,2%_%TIME:~6,2%.txt 

Primera línea determines el PID por nombre del proceso y de usuario.

Entonces PsExec ayuda a llamar jstack en elevated mode con properly escaped redirección del archivo output a jstack*.txt en dir de guión con timestamp included in file name.

Puede que necesite agregar directorios PsExec y JDK a PATH de antemano.

He intentado forzar threaddumps por SendSignal antes, pero nunca funcionó de manera confiable con los procesos de servicio de Windows.

Cuestiones relacionadas