0

I tried to use EJB programmatic timers with IBM Liberty Profile 18.0.0.1. Here is my service.xml:

<feature>ejbLite-3.2</feature>
......
<ejbContainer>
 <timerService nonPersistentMaxRetries="3" nonPersistentRetryInterval="10" />
</ejbContainer>

And here is my bare bone code snippet.

@Stateless
public class BatchSubmissionTimer {
private static final Logger LOGGER = 
Logger.getLogger(BatchSubmissionTimer.class.getName());

@Resource
TimerService timerService;

private Date lastProgrammaticTimeout;

public void setTimer(long intervalDuration) {
    LOGGER.info("Setting a programmatic timeout for "
            + intervalDuration + " milliseconds from now.");
    Timer timer = timerService.createTimer(intervalDuration,
            "Created new programmatic timer");
}

@Timeout
public void programmaticTimeout(Timer timer) {
    this.setLastProgrammaticTimeout(new Date());
    LOGGER.info("Programmatic timeout occurred.");
}

public String getLastProgrammaticTimeout() {
    if (lastProgrammaticTimeout != null) {
        return lastProgrammaticTimeout.toString();
    } else {
        return "never";
    }

}

public void setLastProgrammaticTimeout(Date lastTimeout) {
    this.lastProgrammaticTimeout = lastTimeout;
}

}

This is how my client invokes the timer:

BatchSubmissionTimer batchSubmissionTimer = new BatchSubmissionTimer();
batchSubmissionTimer.setTimer(5000);

However, I got a non-pointer error on injected TimerService. The TimerService wasn't injected successfully. Can anybody shed some lights on this? Appreciate it!

Andy Guibert
  • 41,446
  • 8
  • 38
  • 61
Java guy
  • 33
  • 1
  • 4

1 Answers1

2

In your example, you are instantiating your own instance of BatchSubmissionTimer rather than allowing the container to provide it as an EJB, so the container does not have a chance to inject a value for the annotated timerService field. There are several ways to access it as an EJB, including lookup or injecting it, for example,

@EJB
BatchSubmissionTimer batchSubmissionTimer;
njr
  • 3,399
  • 9
  • 7
  • Thank you very much njr. So what are other ways? – Java guy Jun 26 '18 at 20:21
  • Say I do use @EJB to inject BatchSubmissionTimer, how should I configure my in server.xml? Thanks very much! – Java guy Jun 26 '18 at 20:38
  • With any sort of tuning questions there is no single best way to give out as a general rule. The default configuration for ejbContainer and timerService ought to work, but beyond that, you need to determine what is best for your particular usage. Regarding your other question, the other ways to access an EJB (resource refs, various scoped JNDI names, and so forth) is too broad to fit here. The best I can do is refer you to the EJB spec and give a simple example, which requires the jndi-1.0 feature: InitialContext.doLookup("java:global///BatchSubmissionTimer") – njr Jun 27 '18 at 21:49
  • Thanks a lot njr. If I just want to do a local ejb, I don't have to do the JNDI lookup, right? – Java guy Jun 28 '18 at 19:01