First I'd like to clear out that I know what a NullPointerException
is and how to handle that. My question is about how to access the @ApplicationScoped
bean that is created on server startup, through the scheduler that I would like to run once a day. All I get now is a new bean, which is null
at the beginning and not the already created bean.
The scheduler does the initiation of the bean so I end up with two beans, one that is updated by the scheduler (all the time) and one that is used when navigating in the web application.
So...
I have a web application with a @ApplicationScoped
bean. This one is loaded from database on Tomcat startup.
This means that if something is changed in database in some other way than through the web application the changes won't be viewable until the Tomcat has been restarted.
So I thought I could make a Schedule to reload this @ApplicationScoped
bean on a specific time during the day. The trouble is that I get a whole new @ApplicationScoped
bean.
So how should I do to get the current bean updated and not a new one?
I've tried the solution in this tread: Refresh/Reload Application scope managed bean without any luck. My bean is still null
.
I've also looked at the following threads without really solving my problem:
application scoped bean's view is not updated
Access ApplicationScoped bean through ServletContext
My ApplicationBean.java
import javax.enterprise.context.ApplicationScoped;
@Named(value = "applicationBean")
@ApplicationScoped
public class ApplicationBean {
@PostConstruct
public void init() {
//load variables from db
}
}
My ScheduleTaskConfig.java
@WebListener
public class ScheduleTaskConfig implements ServletContextListener {
private ScheduledExecutorService scheduler;
@Override
public void contextInitialized(ServletContextEvent event) {
Reloader reloader = new Reloader(event.getServletContext());
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(reloader, 2, 3, TimeUnit.MINUTES);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
scheduler.shutdownNow();
}
}
My Reloader.java
public class Reloader implements Runnable {
private ServletContext context;
public Reloader(ServletContext context) {
this.context = context;
}
@Override
public void run() {
ApplicationBean applicationBean = (ApplicationBean) context.getAttribute("applicationBean");
if (applicationBean != null) {
applicationBean.init();
}
}
}
I just don't know what is wrong. I don't understand how to solve this.
I know I've written that the schedule should run every 3 minutes but when I get this to work the schedule should run once a day.
Is there a better way to do this or have I just forgotten something? I've googled the whole day without getting forward so I really need help. Thank you.
Edited: So my servlet context is up and my listener is notified before my application context is up? What if I use the webpage then my application context is up (?) but my scheduler still doesn't work, the bean in the scheduler is still a new one and not the one I've been using when navigating in the web application. Or am I just confused over this? :) Thank you for your help.
Edited: I'm using Primefaces 6.0 and I suppose this bean is a JSF bean. Other beans used are Spring beans imported from a model class. Sorry for the confusion I have removed the Spring notation and added Primefaces instead. I hope this clears things out. Thank you