5

I want to create a timer EJB3 when a stateless bean is created in the pool. But if I use @PostConstruct I get the exception:

java.lang.IllegalStateException: [EJB:010193]Illegal call to EJBContext method. The bean is in "null" state. It cannot perform 'getting the Timer Service' action(s). Refer to the EJB specification for more details.

If container calls @PostConstruct, the bean ins't null. So, why I get this exception?


CLASS

@Stateless
public class TestBean implements TestLocal {

    @Resource
    TimerService timerService;

    @PostConstruct
    public void startTimer() {
        if (timerService.getTimers().size() == 0) {
            timerService.createTimer(1 * 1000, 1 * 1000, null);
        }
    }

    @Override
    public void test() {        
    }

}

INTERFACE

@Local
public interface TesteLocal {

    void test();

}

SERVLET

public class TestServlet extends HttpServlet {
    @EJB
    private TestLocal test;

    protected void doGet(....) throws .... {
        test.test();
    }
}

DETAILS

I'm using weblogic server 11g.

Topera
  • 12,223
  • 15
  • 67
  • 104

3 Answers3

7

You can NOT use a @PostConstruct to create a timer in a stateless bean EJB 3. See this blog How to use EJB 3 timer in a weblogic 10 cluster environment for the explanation. Even the blog was talking about weblogic, but the explanation should apply to other app servers also.

Mike
  • 121
  • 1
  • 2
2

Container will not allow for timerService in method annotated with @PostConstruct of Stateless Session Bean. If you want to use timerService in method annotated with @PostConstruct the go for Singleton session bean(@Singleton).

-3

I'm not 100% sure but I think that the bean class must implement javax.ejb.TimedObject or have a method annotated with @Timeout to use EJB timers. Example:

@Stateless
public class TestBean implements TestLocal {

    @Resource
    TimerService timerService;

    @PostConstruct
    public void startTimer() {
        if (timerService.getTimers().size() == 0) {
            timerService.createTimer(1 * 1000, 1 * 1000, null);
        }
    }

    @Timeout
    @TransactionAttribute(value=REQUIRES_NEW)
    public void timeoutCallback(Timer timer) {
        ...
    }

}

Does WebLogic still complain with the above code?

PS: In any case, the error you currently get is very poorly reported, you should probably open a case.

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • I follow your example, making 2 changes: a) TestLocal has a method to be implemented by TestBean (without this, weblogic can't deploy) b) a create a servlet that calls the EJB. The error still happens. – Topera Aug 18 '10 at 01:06
  • @Topera I was really not sure (I'm not even sure that what I suggested is mandatory with EJB 3.0). I may be wrong but this looks like a bug. I suggest contacting the support – Pascal Thivent Aug 19 '10 at 21:21
  • 1
    Indeed, this code won't run, as Mike said. Timers can't be accessed or started from a @Postconstruct method. – mikek Jun 17 '11 at 12:19