Eu sou um desenvolvedor trabalhando no OS X no Eclipse. Um bug que eu tenho trabalhado para corrigir em um aplicativo da web resulta em algum comportamento muito estranho ao redefinir uma instância do Tomcat, resultando na seguinte mensagem de erro ao forçar um desligamento e reinicialização do servidor (ele não shutdown cleanly, provavelmente devido ao bug que estou tentando corrigir, então eu preciso de kill
it, kill -9 <pid>
e "force terminate" interno do Eclipse dão o mesmo comportamento):
Several ports (23432, 34543) required by Tomcat v8.0 Server at
localhost are already in use. The server may already be running in
another process, or a system process may be using the port. To start
this server you will need to stop the other process or change the port
number(s).
Tudo bem, eu trabalhei com esse material há muito tempo e normalmente isso significa que o Tomcat ainda está rodando em algum lugar, só precisa removê-lo e as coisas funcionarão.
No entanto, lsof(1)
não lista lista nenhum processo ativo nessa porta:
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
Eu verifiquei que as portas estão realmente em uso através de um pequeno script python, apenas para ter certeza de que o Eclipse não está errado:
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()
Simples, tente ligar à mesma porta e lançar uma exceção se não funcionar.
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
Existe um processo zombie (java)
flutuando com o PID do Tomcat que eu matei originalmente, e eu suspeito que esse sujeito tenha algo a ver com isso:
user@yosemite ~ % ps wwwaux | grep java | grep -v 'grep'
user 975 0.0 0.0 0 0 ?? ?E 11:15AM 0:00.00 (java)
Existe qualquer jeito que eu possa liberar as portas que estão em uso sem reiniciar ou sair?
Isso acontece toda vez que eu recrojo meu bug e é um grande desperdício de tempo ter que parar e reinicializar em cada passagem de depuração.
No Linux, eu provavelmente rodaria gdb -p PID
e close(<fdnum>)
, mas no OS X eu não consigo nem encontrar qual (se algum) descritor de arquivo se refere a esse endereço.