Reputation: 3808
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
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