Search code examples
javajpajbossejbservlet-listeners

ServletContextListener scheduler carry out a task - then stalls on EJB method call to persist into a database in JBOSS 7.1


I have a ServletContextListener that runs a tasks every 20 seconds - That task is to listen on a folder and check for new files and if found import the new file into a database. This is set up using the answer given from this question: Spawning threads in a JSF managed bean for scheduled tasks using a timer

Java Code for ServletContextListener

@WebListener
public class Listener implements ServletContextListener {

     private ScheduledExecutorService scheduler;

        @Override
        public void contextInitialized(ServletContextEvent event) {
            scheduler = Executors.newSingleThreadScheduledExecutor();

            scheduler.scheduleAtFixedRate(new MyTask(), 0,20, TimeUnit.SECONDS);
        }

        @Override
        public void contextDestroyed(ServletContextEvent event) {
            scheduler.shutdownNow();
            System.out.println("Terminating the Listener");
        }
}

Java Code for MyTask

public class MyTask implements Runnable{

@EJB
LoaderManager loaderManager;

@Schedule(hour="0", minute="0", second="0", persistent=false)
public void run() {

                //Some unnecessary code left out


        if (itIsOkToImportTheDatabase)
            {


            loaderManager.loadDatabase(pathToNewFile);


            if (thisistrue) {
                //doesnt matter
            } else {
                //doesnt matter
            }
        }

        else

        {
            // not important
            }
        }
    }

}

Java Code for LocalBean to import the data to the database via JPA

@Stateless
@LocalBean
public class LoaderManager implements LoaderManagerDAO{

    @Inject
    private EntityManager em;
    private Row row = null;
    private FileInputStream inp;
    private Workbook wb;

    public void loadDatabase(String FileLocation) {

        InputStream inp = null;

// some file set up stuff, using Apache POI

Sheet sheet1 = wb.getSheetAt(0);

for (int i = 1; i <= sheet1.getLastRowNum(); i++) {
            // loop through each row

            em.persist(elementsInRow);

        }

The listener does check the folder successfully - but when the code to import the database is called - it just seems to stall, with no error coming up on the JBOSS console. I have tried to inject the LoaderManager in many ways but have hit a brick wall... The method call loaderManager.loadDatabase(pathToNewFile); does not reach the LoaderManager class (Checked with print statements) unless i use instantiate it like

LoaderManager loaderManager = new LoaderManager():

.. which im pretty sure is wrong, and even with that it only gets as far as (but doesnt execute, checked via print statements)

em.persist(elementsInRow);

None of the rest of the functionality of the WebApp seems to be affected by any of this, Any help/advice would be much appreciated,

Cheers.


Solution

  • Your code makes very little sense. Injections are wrong and use of unmanaged threads is generally a bad idea in Java EE environment. Since you're using a container with Java EE 6, consider using singleton startup bean and timerservice:

       @Startup
       @Singleton
       public class SchedulerBean {
         @Resource
         private TimerService timerService;
         @EJB
         private LoaderManager loaderManager;
         private Timer timer;
    
         @PostConstruct
         public void init() {
           timer = timerService.createIntervalTimer(20 * 1000, 20 * 1000, new TimerConfig(null, false));
         }
    
         @PreDestroy
         public void deinit() {
           timer.cancel();
         }
    
         @Timeout
         public void schedule(Timer timer) {
            // TODO: Add your checks here
            loaderManager.loadDatabase(databaseLocation);
         }
       }
    

    Also I think that you should be using a singleton bean instead of stateless bean for LoaderManager.