El FacesContext
se almacena como una variable ThreadLocal
en el hilo responsable de la solicitud HTTP que invocó el FacesServlet
, el responsable de la creación de la FacesContext
. Por lo general, este hilo pasa solo por los métodos de beans gestionados de JSF. El FacesContext
no está disponible en otros hilos generados por ese hilo.
En realidad debería también no tienen la necesidad de que en otros hilos. Además, cuando el hilo se inicia y se ejecuta de forma independiente, la solicitud HTTP subyacente continuará procesando la respuesta HTTP inmediatamente y luego desaparecerá. No podrá hacer algo con la respuesta HTTP de todos modos.
que necesita para resolver su problema de manera diferente. Pregúntese: ¿para qué lo necesita? Para obtener algo de información? Sólo tiene que pasar que información al Runnable
durante su construcción en su lugar.
El ejemplo abajo asume que desea acceder a un objeto de ámbito de sesión en el hilo.
public class Task implements Runnable {
private Work work;
public Task(Work work) {
this.work = work;
}
@Override
public void run() {
// Just use work.
}
}
Work work = (Work) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("work");
Task task = new Task(work);
// ...
Si embargo, en última instancia tiene que notificar al cliente, por ejemplo, que el trabajo del hilo ha finalizado, entonces debería buscar una solución diferente de, por ejemplo, agregando un mensaje de caras más o menos. La respuesta es usar "push". Esto se puede lograr con SSE o websockets. Un ejemplo concreto de websockets se puede encontrar en esta pregunta relacionada: Real time updates from database using JSF/Java EE. En caso de que ocurriera utilizar PrimeFaces, mira <p:push>
. En caso de que utilice OmniFaces, mire <o:socket>
.
Sin relación al problema concreto, la creación manual de Runnable
s y desove manualmente los hilos en una aplicación web Java EE es alarmante. La cabeza a la siguiente Q & A a aprender acerca de todas las advertencias y la forma en que realmente se debe hacer: