2015-06-18 1 views
7

Я работаю над небольшим приложением, которое должно подписывать документы с использованием цифровой подписи и выйти. Подпись может быть в архиве 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, а все еще не завершается процесс ...

Я был бы признателен за любые идеи!

+0

Вы пробовали изучить собственные потоки с помощью [Process Explorer] (https://technet.microsoft.com/cs-cz/sysinternals/processexplorer)? Или вы можете создать дамп и попытаться проанализировать его ... Удачи! – vlp

+0

Прошел через [это] (http://stackoverflow.com/a/34012012/5128464) .... – vlp

ответ

1

Это не касается вашей основной причины, но этот метод может быть использован для принудительного завершения JVM :

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#halt(int)

Как говорит Javadoc, использовать с особой осторожностью ;-)

+1

Пропустил, чтобы упомянуть об этом, но я попробовал. Тот же эффект .... –

0

У меня есть некоторые проблемы с sun.security.pkcs11.SunPKCS11 на Windows 8 PCs.This работает для меня:

Runtime.getRuntime().exec("taskkill.exe /F /PID " + name.split("@")[0]); 
Thread.sleep(500); 

 Смежные вопросы

  • Нет связанных вопросов^_^