Не удается отладить Java-службы Windows с помощью jhat, jps, jstack
Я часто показываю jhat, jps, а инструмент jstack - для разработчиков на Linux и Mac. Однако недавно разработчик указал, что они непригодны для использования в Windows, если рассматриваемое приложение Java работает как служба Windows.
A Исправлена ошибка с ошибкой Sun, но она была закрыта из-за бездействия.
Я проверил это для себя, и действительно это кажется правдой, хотя я с трудом могу в это поверить. Вот настройка:
- Tomcat или аналогичный запуск в качестве службы Windows с функцией "Вход в систему" == "Локальная система"
- Пользователь с правами администратора, зарегистрированными на той же машине Windows.
- Администратор открывает Диспетчер задач Windows, может видеть, как работает java.exe
- Администратор открывает консоль, набирает "jps", возвращает список процессов, которые не включают в себя сервисный процесс Tomcat java.
- Как попытка грубой силы получить PID tomcat как службу из диспетчера задач Windows. Тип jstack <pid> . Получите ответ: <pid> нет такого процесса
Это выглядит воспроизводимым в Windows XP, Windows 2003 Server и Windows 7. Версии Java 1.5 и 1.6 дают тот же результат.
Есть ли способ от терминала, даже если он входит в систему как Admin, для "sudo up", чтобы получить JPS и другие инструменты для просмотра java-сервиса?
Ответы
Ответ 1
Чтобы запустить утилиту, вы можете подключиться к сеансу консоли с помощью "mstsc/admin", используя учетную запись (не обязательно точные разрешения, которые должны быть у нее есть, моя была в группе "Администраторы" ) и использовать инструмент sysinternals psexec для запуска в качестве системы. Ниже приведен пример использования jstack.exe:
psexec -s "%JAVA_HOME%\bin\jstack.exe" PID >stack.txt
Где PID - это идентификатор процесса вашего процесса. Возможно, вам также придется подставить реальный путь к вашему JDK в зависимости от вашей конкретной среды.
Кроме того, каталог TEMP должен быть установлен правильно или еще раз инструменты не будут работать.
Ответ 2
У меня были удаленные процессы отладки, выполняемые пользователем SYSTEM, запустив это из командной строки:
c:> time/t
11:18 AM
c:> at 11:19 /interactive cmd.exe
Added a new job with job ID = 1
Используйте время 1 минута в будущем. Когда задание "at" запускает командную строку Windows, она будет запускаться как пользовательская система. Оттуда вы сможете увидеть java-процессы.
Если служба запущена как локальный пользователь (проверьте данные с "mmc% windir%\system32\SERVICES.MSC", дважды щелкнув по этой услуге и выбрав вкладку "Вход" ), вы можете сделать то же самое используя "runas":
runas /user:USERNAME cmd.exe
Ответ 3
Вы получаете только те процессы, которые "принадлежат" вам - тот же идентификатор пользователя.
Можете ли вы подключиться к нему с помощью jvisualvm?
Ответ 4
Я только нашел предложение запустить visuamvm (или другие инструменты) в качестве службы Windows: Контроль процессов Java, выполняемых как служба Windows
Возможно, кто-то еще знает лучшее решение.
Ответ 5
Это мой пакетный файл для записи дампа потока
:: 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
Ответ 6
Вот решение, которое в конечном итоге помогло мне получить стековые трассировки из неподготовленного Java-процесса, запущенного под другим пользователем в терминальной сессии или в качестве службы 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
@for /f "tokens=2 delims==." %%G in ('wmic os get localdatetime /value') do @set datetime=%%G
@set date_time=%datetime:~0,4%_%datetime:~4,2%_%datetime:~6,2%__%datetime:~8,2%_%datetime:~10,2%_%datetime:~12,2%
PsExec.exe /accepteula -h -s -d cmd /c "%JAVA_HOME%\jstack.exe" -l %PID% ^>%~dp0jstack_%date_time%.txt
Первая строка определяет PID по имени процесса и пользователю.
Затем PsExec с принятым EULA помогает вызывать jstack в режиме повышенных прав с правильно экранированным перенаправлением вывода в jstack*.txt
каталоге dir с отметкой времени, включенной в имя файла.
Возможно, вам придется добавить каталоги PsExec и JDK в PATH заранее.
Ранее я пытался принудительно создать поток потоков с помощью SendSignal, но он никогда не работал надежно с процессами службы Windows.