Odio JSF. Me parece una tecnología encorsetada que te complica hasta extremos indecibles cuando quieres salirte un poco del camino que traza. Esto no sería tan tan malo si no tuviese decisiones de diseño tan cuestionables como: ¿a quién se le ocurrió que usar POST para todo era una buena idea? ¿Y el no permitir URLs de acceso directo (bookmarkable)? ¿Y ese ciclo de vida que no encaja con el de los servlets? Será todo lo estándar que Sun/Oracle quiera en JavaEE 6, que tampoco es santo de mi devoción, pero no se lo recomiendo a nadie que quiera hacer una aplicación web, aprovechando los mecanismos de la web.
En fin, después de este desahogo y como supongo que quien llegue aquí estará más o menos igual de confuso, simplemente incluyo el pegote de código necesario para incluir un logout con su correspondiente redirección a la página de inicio. Es la solución más simple y concisa a la que he llegado:
public void logout() {
ExternalContext ctx =
FacesContext.getCurrentInstance().getExternalContext();
String ctxPath =
((ServletContext) ctx.getContext()).getContextPath();
try {
// Usar el contexto de JSF para invalidar la sesión,
// NO EL DE SERVLETS (nada de HttpServletRequest)
((HttpSession) ctx.getSession(false)).invalidate();
// Redirección de nuevo con el contexto de JSF,
// si se usa una HttpServletResponse fallará.
// Sin embargo, como ya está fuera del ciclo de vida
// de JSF se debe usar la ruta completa -_-U
ctx.redirect(ctxPath + "/faces/index.xhtml");
} catch (IOException ex) {
ex.printStackTrace();
}
}
Suerte a los que lidian con este monstruo, por suerte creo que en mi trabajo cambiaremos de framework dentro de poco.