Я разработчик, работающий в OS X на Eclipse. Ошибка, над которой я работал, чтобы исправить в веб-приложении, приводит к некоторому очень странному поведению при сбросе экземпляра Tomcat, приводящему к следующему сообщению об ошибке при принудительном завершении работы и перезапуске сервера (он не будет отключаться корректно, вероятно из-за ошибка, которую я пытаюсь исправить, поэтому мне нужно ее kill
, и kill -9 <pid>
и внутреннее "принудительное завершение" в Eclipse дают одинаковое поведение):
Несколько портов (23432, 34543), необходимых для сервера Tomcat v8.0 на локальном хосте, уже используются. Возможно, сервер уже запущен в другом процессе, или системный процесс может использовать порт. Чтобы запустить этот сервер, вам нужно остановить другой процесс или изменить номер порта (ов).
Это хорошо, я долго работал над этим, и обычно это означает, что Tomcat еще где-то работает, просто нужно удалить его, и все будет работать.
Однако lsof(1)
не перечисляет никаких активных процессов, удерживающих этот порт:
user@yosemite ~ % sudo lsof -Pan -i tcp -i udp | grep 23432
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
launchd 1 root 23u IPv6 0x57073763bfdd9c27 0t0 TCP *:5900 (LISTEN)
launchd 1 root 26u IPv4 0x57073763bfddfb77 0t0 TCP *:5900 (LISTEN)
launchd 1 root 30u IPv6 0x57073763bfdd9727 0t0 TCP [::1]:631 (LISTEN)
launchd 1 root 31u IPv6 0x57073763bfdd9c27 0t0 TCP *:5900 (LISTEN)
launchd 1 root 32u IPv4 0x57073763bfddf2a7 0t0 TCP 127.0.0.1:631 (LISTEN)
launchd 1 root 34u IPv6 0x57073763bfdd9227 0t0 TCP *:22 (LISTEN)
launchd 1 root 37u IPv4 0x57073763bfdde9d7 0t0 TCP *:22 (LISTEN)
launchd 1 root 41u IPv4 0x57073763bfddfb77 0t0 TCP *:5900 (LISTEN)
launchd 1 root 47u IPv4 0x57073763bfddf2a7 0t0 TCP 127.0.0.1:631 (LISTEN)
...
user@yosemite ~ % sudo lsof -Pan -i tcp -i udp | grep 23432
Я проверил, что порты действительно используются с помощью небольшого скрипта Python, просто чтобы убедиться, что Eclipse не ошибается:
user@yosemite ~ % cat socket_open.py
#!/usr/bin/env python
import sys, traceback, socket
HOST=''
PORT = int(sys.argv[1])
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Attempting to bind '%s':%s" % (HOST, PORT)
try:
sck.bind((HOST, PORT))
print sck.getsockname()
except Exception as exc:
traceback.print_exc()
Достаточно просто, просто попробуйте привязать к одному и тому же порту и выдать исключение, если оно не работает.
user@yosemite ~ % sudo python socket_open.py 23432
Password:
Attempting to bind '':23432
Traceback (most recent call last):
File "socket_open.py", line 10, in <module>
sck.bind((HOST, PORT))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
error: [Errno 48] Address already in use
Существует а (java)
процесс зомби плавающего вокруг с PID на сервере Tomcat , который я первоначально убил, и я подозреваю , что этот человек имеет что - то делать с ним:
user@yosemite ~ % ps wwwaux | grep java | grep -v 'grep'
user 975 0.0 0.0 0 0 ?? ?E 11:15AM 0:00.00 (java)
Есть ли способ , я могу освободить порты, которые используются без перезагрузки или выхода из системы ?
Это происходит каждый раз, когда я воссоздаю свою ошибку, и это огромная трата времени, чтобы останавливаться и перезагружаться при каждом проходе отладки.
В Linux я, вероятно, запустил бы gdb -p PID
и close(<fdnum>)
но в OS X я даже не могу найти, какой (если есть) дескриптор файла ссылается на этот адрес.