Implementei uma classe de SessionListener e no momento da abertura da sessão faço algumas coisas. Depois que passei a usar isso, notei que logo que inicio o Tomcat, alguma vezes ele destrói uma sessão que teoricamente ficou aberta quando ele foi encerrado. Sendo assim, tem como eu pegar todas as sessões abertas em um determinado momento e destruí-las antes de parar e reiniciar o servidor?
Desde que voce tenha os ids de sessao em algum lugar, sim, voce pode fazer tal manipulacao. Voce pode colocar a manipulacao no metodo destroy() da HttpServlet ( herdado de GenericServlet ), mas eh um tanto arriscado, de qualquer maneira.
Rafael
Suponha que eu guarde todos os id’s de sessão em um banco. Como eu faço pra destruir as sessões? Método invalidate(session.invalidate())? E onde entra os id’s pra dizer que estou destruindo a sessão x, y, z,…etc?
Voce nao precisa se preocupar em invalidar a sessao… o container vai estar sendo derrubado mesmo. Mas, de qualquer maneira, chame invalidate() se preferir.
Eu aconselharia guardar os ids em memoria ao inves de um banco de dados.
O que vc esta querendo fazer, mais especificamente?
Rafael
Como falei, algumas vezes que inicio o tomcat, que está integrado com o Apache, ele destrói uma sessão que não foi criada, ninguém abriu página alguma. Dá a entender que está sendo destruída uma sessão que ficou aberta anteriormente, isso está atrapalhando a minha contagem de usuários online. Então queria antes de parar o conteiner de pegar todas as sessões abertas e destruí-las…
Como guardaria em memória? suponha que eu tenha 5 sessões, como vou pegar cada uma e destruir?
Acho que vc esta fazendo com uma abordagem errada. Veja, basta vc tem uma propriedade estatica em alguma classe e controlar ela:
public class ControleSessao {
private static int totalUsuarios;
public static void incrementa() {
totalUsuarios++;
}
public static void decrementa() {
totalUsuarios--;'
}
}
entao, no teu sessionCreated(), vc simplesmente faz
ControleSessao.incrementa();
e no sessionDestroyed() vc faz
ControleSessao.decrementa();
quando vc restartar o Tomcat, a vm vai sair de memoria e entao subir rem um novo processo, fazendo com que o contador comece do zero de novo.
Rafael
Ok, estava fazendo com um atributo de contexto ao invés de um atributo estático. Vi o exemplo em um livro e implementei igual. Sua proposta parece mais fácil e implementei aqui…funcionou, porém o tomcat continua destruindo uma sessão antes mesmo de qualquer outra ser criada…vc nunca viu isso acontecer não?
As sessoes tem um timeout x, que, quando acaba, o sessionDestroyed() eh automaticamente invocado.
De maneira geral nao eh motivo para voce se preocupar. Apenas certifique-se que o contador nunca fique menor que 0.
Rafael
…, mas é exatamente isso que tá acontecendo. No momento que a sessão “fantasma” é destruída o valor tá ficando negativo. Quanto ao time out, qdo eu paro o tomcat ele tinha que destruir todas as sessões independentemente se o timeout acabou ou não, não é isso? Afinal de contas eu estou parando o servidor e teoricamente não teria onde nem como elas sobreviverem até o próximo restart…
Bem, você pode deixar suas sessões mais personalizadas, assim, quando o sessionDestroyed for chamado, cheque se ela foi criada pela sua aplicação … caso sim, decremente o valor 
Bom, simplesmente nao decremente se ja estiver em 0…
Rafael