0

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

Community
  • 1
  • 1
user2018311
  • 105
  • 2
  • 13
  • Disagree with the duplicate. Sure his bean is null, but he's not asking what null means. This is a Spring configuration issue. – Craig Otis Sep 15 '16 at 20:05
  • Sorry but yes I do know what a Nullpointer is. I know my applicationBean is null. I've run my app in debug, I know the bean is null. I want to solve the reason why it's null! So I've tried to put @PostConstruct, I've tried to use a constructor but I got a new bean and I don't want a new bean to be created. I tried to use FacesContext instead of ServletContext but then I just couldn't get the scheduler to work. I need help to sove this, with new ideas or someone to explain to me what I am missing! Or if this is just impossible with this approach or if there is a better way to do this. – user2018311 Sep 16 '16 at 05:36
  • I think your application beans are not normally available in the `ServletContextListener`, as this listener is normally fired when the *servlet* context is up, but prior to your application context having been initialized. Is it possible to create your `reloader` as a bean as well? – Craig Otis Sep 16 '16 at 11:52
  • I'm not sure how I could create the reloader as a bean? And I think the servlet context is up? The web application is up and running on Tomcat server, so I assume the context is up. – user2018311 Sep 16 '16 at 12:48
  • Right, but your listener is notified with the servlet context is up, but *before* your application context is. They're different, and your beans aren't available until the second (application) context has been created. – Craig Otis Sep 16 '16 at 13:12
  • 1
    I would like this question to be reopened. I have edited the question so I think it's clear now that it is not about how to solve a nullpointer. Thank you! – user2018311 Sep 20 '16 at 05:39
  • 1
    Your question is unclear, as it doesn't explain how your application scoped bean comes into existince... Is it through spring then the bean will not be available in the `ServletContext` but in the `ApplicationContext` and that makes your solution simply not work (nor the ones mentioned in your links). If it is JSF then why is this question labelled with Spring... – M. Deinum Sep 27 '16 at 08:44
  • Please **know** what technologies you use and which ones are involved in your problem – Kukeltje Sep 28 '16 at 22:29
  • Duplicate? http://stackoverflow.com/questions/22781554/cdi-eager-application-scoped-bean or is http://stackoverflow.com/questions/3600534/how-do-i-force-an-application-scoped-bean-to-instantiate-at-application-startup better? – Kukeltje Sep 28 '16 at 22:30

0 Answers0