3

I have a ServletContextListener that is running on start up of my JBOSS 7.1 server. This essentially listens on a folder and waits for new files and waits for new excel files at present and renames them.

Java

public class StagedFolderListener implements ServletContextListener {

    @Inject
    TableDao tableDao;

@Inject
ImportDatabase import;

public void contextInitialized(ServletContextEvent e) {
    System.out.println("Listener starting...");
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {

        @Override
        public void run() 
        {
            ProcessData();
        }
    }, 0, 10000);

}

public void contextDestroyed(ServletContextEvent e) {
    System.out.println("Listener destroyed...");
}

public void ProcessData() {

    String myDirectoryPath = "/home/myStoredFolder";

    File dir = new File(myDirectoryPath);
    for (File child : dir.listFiles()) {
        String extension = "";

        int j = child.getName().lastIndexOf('.');
        if (j > 0) {
            extension = child.getName().substring(j + 1);
        }


        if (fileIsOktoBeImported) {

            // Import the file into the database

                            import.loadDatabase();              


            // Rename the file after processing
        }

        else

        {
            System.out.println("No processing required on file "
                    + child.getName());
        }
    }

}

}

Separately i have another class that reads in excel files and persists the data to the database via JPA and an Entity Manager. This works fine on its own right (i have it linked to a GUI and can import from there) but i need to have the loadDatabase() method called within my ServletContextListener to import the new excel files that come in. I have tried to inject the ImportDatabase into the ServletContextListener and call the loadDatabase() method but i get a null pointer exception when the EntityManager persists to the database.

Java

@Stateful
@LocalBean
public class ImportDatabase implements TableDao{
@Inject
private EntityManager em;   
Row row = null;
FileInputStream inp;
Workbook wb;

public void loadDatabase()
{

 Load data into the Database via JPA

}

Updating Java to include EntityManager producer

Java

@Stateful
@RequestScoped
public class Resources{

    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    private EntityManager em;

    @Produces
    public EntityManager getEm() {
        return em;
    }
}

What is the best way to have my loadDatabase() method called in the ServetContextListener?

Any help much appreciated,

update

Im now getting an error when injecting the ImportDatabase class into the servletContextLIstener

Error

1:15:06,447 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/mast]] (MSC service thread 1-1) Error configuring application listener of class com.ericsson.listener.StagedFolderListener: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:163) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:85) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.web.deployment.component.WebComponentInstantiator$1.(WebComponentInstantiator.java:57) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]

Obviously im doing something wrong here ...just not sure what, any help much appreciated!

Cheers

user1694873
  • 473
  • 1
  • 11
  • 21
  • 3
    The EntityManager is normally not accessibe for CDI injection `@Inject`. Do you have an appropriate producer? Wthout it the reference will be `null` – kostja Mar 26 '13 at 10:12
  • +1 to kostja, you can't simply @Inject an entity manager. You need to access it via a PU (normally this is done on a producer method). Why dont you inject the class that already setup to do this into your servlet listener? – Perception Mar 26 '13 at 10:19
  • 1
    Just updated there - cheers @Perception will try that – user1694873 Mar 26 '13 at 10:21
  • 1
    Hi again @Perception i mistakenly said that i injected the EntityManager into my ServletContextListener, i should have said what i tried was to inject the ImportDatabase class and call the loadDatabase() method, this is where the null pointer for the Entity Manager pops up. (It does read the values from the excel sheet as i can print these out to the screen - but when it tries to persist i get the null pointer - apologies for the confusion earlier...first time really asking a question on stack :) ) Any further ideas ? Cheers – user1694873 Mar 26 '13 at 10:40
  • @Nedved85 - Please update your question with the code you are using to inject your import database class into the servlet listener. – Perception Mar 26 '13 at 10:45
  • 1
    @Perception just updated - now strangely getting an error - see code above if you get the chance - thanks – user1694873 Mar 26 '13 at 11:24
  • 2
    Why are you injecting both `TableDAO` and `ImportDatabase`? You need one or the other. Also, your current producer is request scoped, which will prevent it from being resolved in the context of a servlet listener (request scope won't be active when the listener is being initialized). – Perception Mar 26 '13 at 11:32
  • 1
    Thanks, the combination of your answers and spiritwalkers below has solved the problem - i just injected the ImportDatabase into the servletContextLister as given by spiritwalker below and also removed the RequestScoped from my Resources class (producer) - its my first time on here - i cant mark yours as an answer @Perception as it was just a comment? Thanks very much – user1694873 Mar 26 '13 at 11:44
  • Unfortunately now i am running into these errors .. Failed to find SFSB instance with session ID && javax.ejb.EJBException: java.lang.IllegalStateException: EntityManager is closed – user1694873 Mar 26 '13 at 12:11
  • 1
    Eeeek, a `TimerTask` in a Java EE listener! Carefully read the answer on http://stackoverflow.com/questions/7499534/applicationscope-bean-that-uses-a-timertask-sheduler-good-or-bad before continuning into disaster. – BalusC Mar 28 '13 at 18:45
  • Hi BalusC - just having a quick look now, still getting errors on this, when i drop out the "@RequestScoped" from my Egenerator class it breaks the build everywhere else but in my listener... - gonna read that answer now and see if it helps – user1694873 Mar 28 '13 at 21:41
  • Hi again BalusC, i applied the logic you set out in the @WebListener public class BackgroundJobManager implements ServletContextListener class and the "@Singleton" public class SomeDailyJob class and there are no errors up until the run method in the SOmeDailyJOb actually begins to import my database (To be accurate - it doesnt begin it at all..it just stalls on the method import.loadDatabase(); with no errors, very strange....The rest of my Web app remains fully functional..withy no errors – user1694873 Mar 28 '13 at 23:46
  • Hi @BalusC i have created a new question for the current position i am in http://stackoverflow.com/questions/15696209/servletcontextlistener-scheduler-carry-out-a-task-then-stalls-on-ejb-method-ca - Any help would be great, thanks. – user1694873 Mar 29 '13 at 10:10

1 Answers1

2

Try injecting your DAO into the listener using the @EJB annotation:

@EJB ImportDatabase importDatabase;

In addition, you don't need to inject both TableDAO and ImportDatabase, pick one or the other. And finally, your current producer is request scoped, which will prevent it from being resolved in the context of a servlet listener (request scope won't be active when the listener is being initialized). I would recommend removing the scope on it.

Perception
  • 79,279
  • 19
  • 185
  • 195
spiritwalker
  • 2,257
  • 14
  • 9
  • Cheers will try that now (Id give you a +1 but im restricted from doing so at the minute with my 0 rating :( ) Thanks – user1694873 Mar 26 '13 at 11:23
  • Just tried to use the EJB notation but still getting the same error as described above – user1694873 Mar 26 '13 at 11:28
  • Thanks very much spiritwalker - that was part of the solution to my problem - see my comment above about how should i mark my answer to both yourself and @Perception ?? – user1694873 Mar 26 '13 at 11:47
  • 1
    @Nedved85 - I incorporated my comment into this answer (hope thats ok with you spiritwalker). You can mark it as accepted at your convenience. – Perception Mar 26 '13 at 12:11