0
votes

We are trying to use ejb 3.1 timer component.

Our needs are very simple. Invoke a method in java class for every minute. For this component to work :

  1. I have executed the DDL that websphere gave to create ejb timer tables for
    oracle database.
    Tables are created at EJBTIMER tablespace

  2. Here is my java stateless bean code @Schedule(minute = "/1", hour = "", persistent = true) public void executeTimer() { // business logic here }

  3. With persistent as true, ejb is trying to look up the created tables but it is ending up with the below exception.

Exception:

[2/5/15 15:06:40:605 EST] 00000000 ContainerHelp E   WSVR0501E: Error creating component com.ibm.ws.runtime.component.CompositionUnitMgrImpl@7a9149c4
com.ibm.ws.exception.RuntimeWarning: Error while processing references for EJB-in-WAR: com.ibm.ejs.container.ContainerException: EJB Timer Service not available for TimedObject EJB: com.ford.doesbatch.inbound.scheduler.DoesBatchScheduler
    at com.ibm.ws.runtime.component.EJBContainerImpl.createNestedModuleMetaData(EJBContainerImpl.java:3434)
    at com.ibm.ws.runtime.component.EJBContainerImpl.createNestedModuleMetaData(EJBContainerImpl.java:726)
    at com.ibm.ws.runtime.component.MetaDataMgrImpl.createNestedModuleMetaData(MetaDataMgrImpl.java:564)
    at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:633)
    at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:967)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:769)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl$5.run(ApplicationMgrImpl.java:2160)
    at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5468)
    at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5594)
    at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2165)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:446)
    at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:389)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:117)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$CUInitializer.run(CompositionUnitMgrImpl.java:995)
    at com.ibm.wsspi.runtime.component.WsComponentImpl$_AsynchInitializer.run(WsComponentImpl.java:496)
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1700)
Caused by: com.ibm.ejs.container.ContainerException: EJB Timer Service not available for TimedObject EJB: com.ford.doesbatch.inbound.scheduler.DoesBatchScheduler
    at com.ibm.ws.runtime.component.WASEJBRuntimeImpl.setupTimers(WASEJBRuntimeImpl.java:527)
    at com.ibm.ws.metadata.ejb.EJBMDOrchestrator.processAutomaticTimerMetaData(EJBMDOrchestrator.java:6347)
    at com.ibm.ws.metadata.ejb.EJBMDOrchestrator.finishBMDInitForReferenceContext(EJBMDOrchestrator.java:8379)
    at com.ibm.ws.ejbcontainer.runtime.AbstractEJBRuntime.finishBMDInitForReferenceContext(AbstractEJBRuntime.java:2572)
    at com.ibm.ws.runtime.component.EJBContainerImpl.createNestedModuleMetaData(EJBContainerImpl.java:3427)
    ... 17 more

Question:

EJB is unable to look up EJBTIMER tablespace. Is there anyway we can setup that in application.py or in IBM webconsole.

1

1 Answers

0
votes

After a bit of analysis, I figured that if your @schedule annotation says persistence as "true" then it will look for the EJB table prefix, which we mention in our application.py for webpshere 8.

Solution:

In my case, all the ejb tables were created under a tablespace called EJBTimer. Apparently, this tablespace had no space allocated.

Lesson learned is, table layout should be executed as given and not to forget allocating space for the new tablespace.

Below is how we mention our ejb table prefix to websphere. So, websphere will read your application.py and learns your EJB timer settings.

EJB_TIMER_SETTINGS=[]
EJB_TIMER_SETTINGS.append(["datasourceAlias"  ,"xxxx/ejbTimerJDBC"])
EJB_TIMER_SETTINGS.append(["datasourceJNDIName"  ,"jdbc/xxxx/ejbTimerJDBC"])
EJB_TIMER_SETTINGS.append(["tablePrefix"  ,"XXXXO13_EJBTIMER_"])
EJB_TIMER_SETTINGS.append(["numAlarmThreads"  ,"2"])
EJB_TIMER_SETTINGS.append(["pollInterval", 60])