Необходимо вызвать System.err.close (), иначе JVM не выйдет. Зачем? - PullRequest
0 голосов
/ 27 июня 2011

У нас есть (очень) многопоточное приложение, которое прошло бы все модульные тесты, но не завершилось бы при запуске из IDE или командной строки. Это приложение не только многопоточное, оно выполняет собственные процессы и записывает стандартные ошибки и стандартные. Проблема была в том, что приложение зависало при выходе. В конце концов, я сократил приложение до тех пор, пока оно не стало идентичным модульным тестам, и оно все равно зависало, поэтому я решил, что JUnit делает то, чего не было при запуске из командной строки.
Когда я вызывал System.exit () в конце main (args), приложение закрывалось, что в итоге привело меня к System.err.close ().
Конечно, приложение никогда не «открывает» System.err или System.out. Он просто пишет им и вызывает flush () после завершения. Я тестировал только на 64-битной Windows, позже протестирую на Linux. JVM - это среда выполнения Java (TM) SE (сборка 1.6.0_24-b07)

Есть идеи, почему JVM не выйдет?

Ответы [ 2 ]

1 голос
/ 27 июня 2011

Кажется, я помню, что когда вы вызываете собственные процессы, вы должны быть осторожны, чтобы полностью прочитать собственные процессы и / или ошибочные потоки, иначе все может заблокироваться.Я думаю, что вам, возможно, придется порождать поток, чтобы справиться с этим.Просто мысль.

0 голосов
/ 27 июня 2011

Все программы в Linux сталкиваются с этой проблемой в некоторой степени.Процесс с открытым файловым дескриптором (и он у вас, очевидно, есть, даже если вы его не открывали специально, он произошел от одной из операций вашей системной команды) не завершится полностью, пока все дескрипторы не будут закрыты.Лучший пример, который я могу вспомнить на данный момент, - это проблема, с которой я столкнулся на работе, когда никогда не завершался сценарий запуска (bash), запускающий процесс Java.Проблема была в том, что мы делали 2> & 1> / path / to / log & , который не закрывает стандартный ввод (дескриптор файла 0).Преобразование его в &> / path / to / log устранило проблему, потому что &> означает все файловые дескрипторы, в то время как другой означает только stdin и stderr.

Ваша проблема похожа, иТот факт, что он многопоточный, усугубляет проблему.

...