Spring AsyncTask: update jsf view component
asynchronous, jsf, spring
Solution
`FacesContext.getCurrentInstance()` returns `null` because it tries to get the context from thread local variable. But because the executing thread was not initialized by JSF (which is done by `javax.faces.webapp.FacesServlet`) but created by executor then the thread local variable is `null`.
I have no idea why `NullPointerException` does not occur sometimes. By default `SimpleAsyncTaskExecutor` creates new thread each time unless you specify a thread pool. When I recreated the example it happened every time. Maybe it does but is not logged properly...
To solve your problem you need to resort to polling. For instance you can use property of backing bean to indicate that job was finished.
@Named("someBean")
@SessionScoped
public class SomeBean {
private volatile boolean jobDone = false;
public String execute() {
SimpleAsyncTaskExecutor tasks = new SimpleAsyncTaskExecutor();
tasks.submitListenable(new Callable<String>() {
public String call() throws Exception {
//Do long time taking job in approximately 16 seconds
doTheBigJob();
jobDone = true
return "";
}
});
return null;
}
public boolean isJobDone() {
return jobDone;
}
}
On your page you enter component which is rendered when `jobDone==true`. For instance:
<h:outputText id="jobDoneText" rendered="#{someBean.jobDone}" value="Job finished"/>
Then using polling and AJAX you update your current page.
In pure JSF the only way to do polling is to use combination of JavaScript and JSF AJAX requests.
Alternatively you can use Primefaces component `p:poll` to poll for changes.
<p:poll interval="1" update="jobDoneText" />
More about polling in JSF can be found in answers to the following question: JSF, refresh periodically a component with ajax?
Problem
I have a long run job must run in background and after it finished I want to update jsf view component. I used `SimpleAsyncTaskExecutor` to do the work. It works good but when comming to updating ui then I am getting `NullPointerException`. Here is my code ``` SimpleAsyncTaskExecutor tasks = new SimpleAsyncTaskExecutor(); tasks.submitListenable(new Callable<String>() { @Override public String call() throws Exception { //Do long time taking job in approximately 16 seconds doTheBigJob(); //then update view component by it's id FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(myComponentId); return ""; } }); ``` Not: When the time is short (like 2 seconds), no `NullPointerException` occurs Thanks in advence.