Question

I'm to trying use a TimerService instance to schedule dynamically some executions on a singleton EJB on a Tomee 1.6.0 server. The scheduling works the first time, but on subsequent executions I get the following error (in the Tomee console) and scheduling seem to stop working in the app:

mar 07, 2014 1:27:06 PM org.apache.openejb.cdi.CdiResourceInjectionService fillInjectionProperties
WARNING: Injection data not found in JNDI context: jndiName='comp/env/myapp.Bean/timerService', target=myapp.Bean/timerService

The EJB trying to achieve this looks like this:

package myapp;

@Singleton
public class Bean implements Serializable {
private static final long serialVersionUID = 1L;

    @Resource
    private transient TimerService timerService;

    private Timer oldTimer = null;

    public Bean() {
        super();
    }

    public void schedule(
            @Observes(during = TransactionPhase.AFTER_COMPLETION) @ScheduleEvent ScheduleExpression schedule) {

        if (oldTimer != null) {
            oldTimer.cancel();
        }

        try {
            return oldTimer = timerService.createCalendarTimer(schedule, new TimerConfig("TIMER", true));
        } catch (IllegalArgumentException e) {
            throw new EJBException(e);
        }
    }

    @Timeout
    @Lock(LockType.READ)
    private void timeout(Timer timer) {
          // Do stuff...
    }
}

The method schedule of Bean is triggered on an event fired from ConfigBean, which monitors a ".properties" file (where the schedule timing information is stored) and fires the necessary event whenever it detects any changes on it:

@Singleton 
@Startup 
public class ConfigBean { 
    @Resource 
    private TimerService timerService; 
    @Inject 
    @ScheduleEvent 
    private Event<ScheduleExpression> scheduleEvent; 

    @PostConstruct 
    private void init() { 
        timerService.createTimer(1000L, 1000L, "CONFIG UPDATED"); 
    } 

    public void load() { 
        scheduleEvent.fire(ScheduleExpressionFactory.parse(/*string data*/)); 
    } 

    @Timeout 
    private void timeout(Timer t) { 
        if ("CONFIG UPDATED".equals(t.getInfo()) && updated()) { 
            load(); 
        } 
    } 

    private boolean updated() {
        /* return true if config was updated*/
    }

}

Why does Tomee find the injection data the first time, and it doesn't the next ones? How can I get it to work?

Was it helpful?

Solution

I finally solved it! It seems that the @Observes(during = TransactionPhase.AFTER_COMPLETION) annotation was causing the issue. Removing the parameter and leaving simply @Observes did the trick for me.

I don't know really why, but the problem, perhaps, is related to transactional behaviour implied in TransactionPhase.AFTER_COMPLETION. The default behaviour of the method after removing that is non-transactional (see documentation).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top