I want to schedule recurring background tasks using ManagedScheduledExecutorService
. I get my Runnable
s/Callable
s via an Instance
, so I have injection capabilities available inside my tasks.
My application runs on TomEE 7.0.0-SNAPSHOT webprofile
.
As these tasks are accessing the database they need a transaction. However, inside the Runnable
/Callable
no transaction is active.
The documentation for ManagedScheduledExecutorService states that
If a transaction is required, use a javax.transaction.UserTransaction instance. A UserTransaction instance is available (...) by requesting an injection of a UserTransaction object using the Resource annotation.
However, the injected
@Resource
private UserTransaction userTransaction;
is null
when invoking the task.
Another approach I took was to inject a stateless EJB into my task, hoping that this would create a transaction for me.
This resulted in the following exception on startup:
SEVERE: CDI Beans module deployment failed
java.lang.IllegalStateException: no interface to proxy for ejb StatelessEjb, is this is a MDB maybe you shouldn't use a scope?
at org.apache.openejb.cdi.CdiEjbBean.createEjb(CdiEjbBean.java:252)
at org.apache.openejb.cdi.CdiPlugin.getSessionBeanProxy(CdiPlugin.java:224)
at org.apache.webbeans.container.BeanManagerImpl.getEjbOrJmsProxyReference(BeanManagerImpl.java:951)
at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:777)
at org.apache.webbeans.container.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:651)
at org.apache.webbeans.inject.AbstractInjectable.inject(AbstractInjectable.java:111)
at org.apache.webbeans.inject.InjectableConstructor.createParameters(InjectableConstructor.java:109)
at org.apache.webbeans.inject.InjectableConstructor.doInjection(InjectableConstructor.java:72)
at org.apache.webbeans.portable.InjectionTargetImpl.newInstance(InjectionTargetImpl.java:190)
at org.apache.webbeans.portable.InjectionTargetImpl.produce(InjectionTargetImpl.java:173)
at org.apache.webbeans.portable.AbstractProducer.produce(AbstractProducer.java:172)
at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:127)
at org.apache.webbeans.component.ManagedBean.create(ManagedBean.java:67)
at org.apache.webbeans.context.DependentContext.getInstance(DependentContext.java:68)
at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:124)
at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:785)
at org.apache.webbeans.inject.instance.InstanceImpl.create(InstanceImpl.java:306)
at org.apache.webbeans.inject.instance.InstanceImpl.get(InstanceImpl.java:123)
(...)
I've created a small test case project on Github. It contains two branches, illustrating the problems mentioned above.
@Stateless
EJB work normally as all instances are obtained using injection?@Resource
injection for the UserTransaction
fail?Using CDI to get it should fix it:
@Inject
private UserTransaction userTransaction;
edit: the issue has been fixed for @Resource case: https://issues.apache.org/jira/browse/TOMEE-1672