Я работаю над небольшим приложением, которое должно подписывать документы с использованием цифровой подписи и выйти. Подпись может быть в архиве PKCS # 12 (файл .pfx) или на устройстве смарт-карты.JVM висит на выходе
Работа с файлом pfx проста и работает нормально.
Однако, иногда с использованием устройства смарт-карты процесс зависает на ПК с Windows 8.
Документ подписан правильно, но процесс не завершается. Он просто висит.
Я использую Солнце PKCS # 11 поставщика - sun.security.pkcs11.SunPKCS11
В основном я делаю это:
SunPKCS11 provider = new SunPKCS11(configuration);
Security.addProvider(provider);
..... some work .....
provider.logout()
Security.removeProvider(provider);
Теперь ... даже если я называю System.exit(0)
или выбросить исключение в конце из метода main
, я могу видеть stacktrace на выходе, но процесс не завершается.
Я добавил крюк выключения, чтобы убедиться, что он выполнен, и это, то есть JVM пытается остановить.
Развертывание происходит редко, только на ПК с Windows 8. Пробовал с помощью разных смарт-карт, и это происходит только с карточками, которые используют cmp11.dll
(dll предоставляются от продавцов смарт-карт).
Используя ту же DLL для связи с смарт-карты, однако, прекрасно работает на Windows 7, XP или некоторых ОС Windows 8 ПК
Запуск его с Java 8, Update 45, на x86 или x64 ОС Windows 8
Пытался получить нить дамп, чтобы увидеть, что висит:
public static void main(String[] args) {
// do my job, register provider, sign documents, remove provider ...
for(int i = 0; i < 20; ++i) {
System.err.println("Sleep... " + i);
Thread.sleep(2 * 1000);
}
System.err.println("Exiting...");
}
Если я исполняю jstack -l 3232 > dump.log 2>&1
когда Sleep... x
печатает, все выглядит нормально.
Однако, если я исполню jstack -F -l 3232 > dump2.log 2>&1
когда Exiting...
печатается и приложение виснет (с использованием -F
, так как процесс зависает), я получил следующее:
Attaching to process ID 3232, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.45-b02
Deadlock Detection:
No deadlocks found.
Thread Exception in thread "main"
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.tools.jstack.JStack.runJStackTool(JStack.java:140)
at sun.tools.jstack.JStack.main(JStack.java:106)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: Windbg Error: GetThreadIdBySystemId failed!
at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.getThreadIdFromSysId0(Native Method)
at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.getThreadIdFromSysId(WindbgDebuggerLocal.java:284)
at sun.jvm.hotspot.debugger.windbg.amd64.WindbgAMD64Thread.getThreadID(WindbgAMD64Thread.java:88)
at sun.jvm.hotspot.debugger.windbg.amd64.WindbgAMD64Thread.toString(WindbgAMD64Thread.java:81)
at java.lang.String.valueOf(String.java:2982)
at java.io.PrintStream.print(PrintStream.java:683)
at sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess.printThreadIDOn(Win32AMD64JavaThreadPDAccess.java:114)
at sun.jvm.hotspot.runtime.JavaThread.printThreadIDOn(JavaThread.java:265)
at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:79)
at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:45)
at sun.jvm.hotspot.tools.JStack.run(JStack.java:66)
at sun.jvm.hotspot.tools.Tool.startInternal(Tool.java:260)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:223)
at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
at sun.jvm.hotspot.tools.JStack.main(JStack.java:92)
... 6 more
можно увидеть процесс с PID 3232 в задаче менеджер!
Любая идея, почему это не заканчивается или почему jstack
не удается?
EDIT
Хорошо, попытался извлечь подписание в отдельном процессе, выполнить его с Runtime.exec
, а затем убить его с Process.destroy
... но не похоже, чтобы помочь. Детский процесс все еще остается в диспетчере задач.
Aaaaand ...Теперь у меня нет другого выбора, кроме как сделать это убить себя;. (
try {
String name = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
Runtime.getRuntime().exec("taskkill.exe /F /PID " + name.split("@")[0]);
}
catch(Throwable t) {
Runtime.getRuntime().exec("taskkill.exe /F /IM java.exe");
}
EDIT 2
Пробовал с Runtime.halt
, а все еще не завершается процесс ...
Я был бы признателен за любые идеи!
Вы пробовали изучить собственные потоки с помощью [Process Explorer] (https://technet.microsoft.com/cs-cz/sysinternals/processexplorer)? Или вы можете создать дамп и попытаться проанализировать его ... Удачи! – vlp
Прошел через [это] (http://stackoverflow.com/a/34012012/5128464) .... – vlp