Farouk Alhassan
Farouk Alhassan

Reputation: 3808

Exception in long running Thread in EJB 3.1 StartUp singleton postconstruct method

Hi a long running thread that starts up in Postconstruct and updates database periodically.

Looks like this

    public void postconstruct() {
    Runnable runnable;
    runnable = new Runnable() {
        @Override
        public void run() {
            int interval = poissonRandomNumber(15);
            while (true) {
                try {
                    Map<Account, AccountUpdate> recentUpdates =
                            simulator.getRecentUpdates(tickDAO, securityDAO);
                    for (Map.Entry<Account, AccountUpdate> entry : recentUpdates.entrySet()) {
                        Account account = entry.getKey();
                        //                            String realised = getAccountReturn(parts, account);
                        Account accountByName = accountDAO.findAccountByName(account.getName());
                        if( accountByName == null  )
                        {
                            account.setAccountId(null);
                            accountByName = accountDAO.create(account);
                        }
                        int realised = new Random().nextInt(50);
                        boolean nextBoolean = new Random().nextBoolean();
                        realised = nextBoolean == true ? realised : -realised;
                        AccountUpdate accountUpdate = entry.getValue();
                        accountUpdate.setAccountId(accountByName);
                        accountUpdate.setDateCreated(new Date());
                        accountUpdate.setUnRealisedPL(new BigDecimal(realised));
                        accountUpdateDAO.create(accountUpdate);
                    }
                    Thread.sleep(interval);
                } catch (Exception ex) {
                    Logger.getLogger(ApplicationManager.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    };
    Thread tickThread = new Thread(runnable);
    tickThread.start();

Whenever I startup the application i get lots of exceptions because it looks like the Container is not ready

I need to know how best to use DAOs and also how to detect if the conytainer is Ready

The exception is as shown below

SEVERE: java.lang.NullPointerException
at com.sun.ejb.containers.util.pool.NonBlockingPool.returnObject(NonBlockingPool.java:285)
at com.sun.ejb.containers.StatelessSessionContainer.releaseContext(StatelessSessionContainer.java:602)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2055)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
at $Proxy270.create(Unknown Source)
at ucl.atrade.rnpvms.server.services.ApplicationManager$1.run(ApplicationManager.java:126)
at java.lang.Thread.run(Thread.java:722)

SEVERE: javax.ejb.EJBException: Attempt to invoke when container is in Undeployed
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1999)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
    at $Proxy265.findSecurityBySymbol(Unknown Source)
    at ucl.atrade.rnpvms.server.datafeed.AccountUpdateSimulator.getRecentUpdates(AccountUpdateSimulator.java:74)
    at ucl.atrade.rnpvms.server.services.ApplicationManager$1.run(ApplicationManager.java:108)
    at java.lang.Thread.run(Thread.java:722)

Upvotes: 1

Views: 4408

Answers (1)

perissf
perissf

Reputation: 16273

As well explained in this link,

The EJB specification assigns to the EJB container the responsibility for managing threads. Allowing enterprise bean instances to create and manage threads would interfere with the container's ability to control its components' lifecycle.

This means that using Runnable in your EJB is not the way to go.

If you want to run some code with a given frequency, you can use a Timer Service.

If on the other way you need to run some code when an update to the db is done, i.e. asynchronously, you have to use other techniques like JMS, or database triggers, or Persistence Context sharing / propagation, or Entity Listeners, depending on your application's requirements.

Upvotes: 2

Related Questions