ps0604
ps0604

Reputation: 1071

Invoke an EJB from a Quartz job

I have a Java EE application that runs on Wildfly and I'd like to integrate it with the Quartz Scheduler. This is how I envision to invoke an EJB from a Quartz job (since I don't know the name of the EJB class at compile time, I use a lookup):

public class MyJob implements Job {

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {        

        InitialContext ic = new InitialContext();
        MyInterface bean = null;
        try {
            String beanClassName  = getItFromSomewhere();
            bean = (MyInterface) ic.lookup("java:module/" + beanClassName );
        } 
        catch (NamingException e) {
            e.printStackTrace();
        }

        bean.myMethod();
     }
}

Is this approach correct? The container wouldn't know about the Quartz job when it's initiated, is that an issue?

Upvotes: 2

Views: 1110

Answers (2)

Alex Mi
Alex Mi

Reputation: 1459

Here is your answer provided by the Quart'z developers on GitHub:

https://github.com/quartz-scheduler/quartz/blob/master/quartz-jobs/src/main/java/org/quartz/jobs/ee/ejb/EJBInvokerJob.java

To summarize: Your approach is right, in your MyJob class you correctly create an InitialContext() to search of the EJB instance you would like to invoke. You cannot put an instance of the EJB in the JobContext, as suggested by the previous answer, because in case there is a server restart between the scheduling of the Job and its invocation, you have no guarantee that an instance of the EJB you want will be "injected" in the JobContext.

Upvotes: 0

LppEdd
LppEdd

Reputation: 21114

Imho a cleaner alternative is passing the EJB instance via the Job's JobExecutionContext

When preparing the Job

final JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(MY_INTERFACE, myInterface);

final Job myJob =
    JobBuilder.newJob(MyJob.class)
              .setJobData(jobDataMap)
              .build();

Inside Job#execute

final JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
final MyInterface myInterface = (MyInterface) jobDataMap.get(MY_INTERFACE);

A Quartz Job implementation shouldn't be aware at all of the JavaEE container in which it is operating. This will will ease the process of updating your code/architecture in the long term.
Also, your Job should only care about its only duty, not about getting the required dependencies.
Think about the JobDataMap as a strange kind of Dependency Injection.

Upvotes: 2

Related Questions