4

Context

I want to schedule recurring background tasks using ManagedScheduledExecutorService. I get my Runnables/Callables via an Instance, so I have injection capabilities available inside my tasks.

My application runs on TomEE 7.0.0-SNAPSHOT webprofile.

Problem

As these tasks are accessing the database they need a transaction. However, inside the Runnable/Callable no transaction is active.

User transaction

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.

Stateless bean

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)
(...)

Test case

I've created a small test case project on Github. It contains two branches, illustrating the problems mentioned above.

Questions

  • Shouldn't the @Stateless EJB work normally as all instances are obtained using injection?
  • Why does @Resource injection for the UserTransaction fail?
MWiesner
  • 8,868
  • 11
  • 36
  • 70
Schroenser
  • 289
  • 1
  • 7

1 Answers1

5

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

Romain Manni-Bucau
  • 3,354
  • 1
  • 16
  • 13
  • Thanks! Any idea why the stateless EJB doesn't work? – Jan Dörrenhaus Dec 01 '15 at 18:22
  • 3
    likely the same issue as the @Resource one (used too early, if you use a singleton startup all your code should be fine) – Romain Manni-Bucau Dec 01 '15 at 22:14
  • Thank you. I updated both branches of my test case according to your input. – Schroenser Dec 02 '15 at 09:41
  • @rmannibucau perhaps offtopic, but since this question is about TomEE 7 and it still hasn't been released, is there any target release date for 7? – dexter meyers Dec 02 '15 at 15:37
  • This is mainly a legal question but for a plain tomee - and from user point of view - OpenJPA is the big thing to make moving (from JPA 2.0 to 2.1) but using plume you have almost everything of EE 7 already (with eclipselinks instead of OpenJPA). – Romain Manni-Bucau Mar 24 '16 at 14:18