Failed to inject entityManager into Quartz job listener
ssarver Apr 1, 2010 1:39 AM>>>Goal: Inject entityManager into Quartz job listener, so I can modify the RemoteJob entity when Quartz invokes the job listener,
and persist the change.
>>>Using:
* jboss-5.1.0.GA (jboss-ejb3-plugin-1.0.19-installer.jar)
* Quartz quartz-1.7.3.jar
>>>Flow:
RemoteHome.scheduleJob() --> RemoteJobManager.scheduleJob(RemoteJob) --> RemoteJobListener.jobWasExecuted(...)
``
>>>Detail:
I want the job listener to reschedule the job and modify the RemoteJob entity.
Unfortunately, the injected @In EntityManager entityManager is null in the listener.
When I inject the log using @Logger, it is also null.
Why is injection failing in the listener?
Alternatively, I when I did a lookup on the entityManager by doing
Context ctx = new InitialContext();
em = (EntityManager) ctx.lookup(ENTITY_MANAGER);
it was not null. I think it failed when merge was called.
The exception led me to believe that I had to wrap the call in
a transaction. That did not work either.
I think I need to stay within the seam context to get it to work.
How should I proceed to reach my goal?
>>>Source code:
RemoteJobHome.java
///////////////////////////////////////////////////////////////////////////////
@Name("remoteJobHome")
public class RemoteJobHome extends EntityHome<RemoteJob> {
@Logger private Log log;
@RequestParameter Long remoteJobId;
@In RemoteJobManager manager;
@In(create = true)
HostHome hostHome;
public void setRemoteJobId(Long id) {
setId(id);
}
public Long getRemoteJobId() {
return (Long) getId();
}
@Override
protected RemoteJob createInstance() {
RemoteJob remoteJob = new RemoteJob();
return remoteJob;
}
public void load() {
if (isIdDefined()) {
wire();
}
}
public void wire() {
getInstance();
Host host = hostHome.getDefinedInstance();
if (host != null) {
getInstance().setHost(host);
}
}
public boolean isWired() {
return true;
}
public RemoteJob getDefinedInstance() {
return isIdDefined() ? getInstance() : null;
}
@Override
public Object getId() {
return remoteJobId;
}
// Schedule job
public String scheduleJob() throws Exception {
String result = persist();
RemoteJob remoteJob = getInstance();
manager.scheduleJob(remoteJob);
return result;
}
}
/////////////////////////////////////////////////////////////////
File: RemoteJobManager.java
/////////////////////////////////////////////////////////////////
@Name("manager")
@AutoCreate
public class RemoteJobManager {
@Logger Log log;
@In EntityManager entityManager;
public void scheduleJob(RemoteJob remoteJob) {
try {
InitialContext ctx = new InitialContext();
// Lookup scheduler
StdScheduler scheduler = (StdScheduler) ctx.lookup("Quartz");
// Create job
JobDetail jobDetail = new JobDetail(
remoteJob.getId().toString(),
Scheduler.DEFAULT_GROUP,
NoOpJob.class
);
SimpleTrigger trigger = new SimpleTrigger(
"trigger" + remoteJob.getId().toString(),
Scheduler.DEFAULT_GROUP,
remoteJob.getStart(),
null,
0,
0);
RemoteJobListener listener = new RemoteJobListener();
// Set up the listener
scheduler.addJobListener(listener);
// Make sure the listener is associated with the job
jobDetail.addJobListener(listener.getName());
// Schedule the job to run
scheduler.scheduleJob(jobDetail, trigger);
// Update entity
remoteJob.setNext(remoteJob.getStart());
entityManager.merge(remoteJob);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////
File: RemoteJobListener.java
/////////////////////////////////////////////////////////////////////
public class RemoteJobListener implements JobListener {
@In
EntityManager entityManager;
public void jobWasExecuted(JobExecutionContext jec, JobExecutionException jee) {
try {
JobDetail jobDetail = jec.getJobDetail();
RemoteJob remoteJob = entityManager.find(RemoteJob.class, new Long(jobDetail.getName()));
// Compute delay (ms)
Long delay = 10000;
Date date = new Date(System.currentTimeMillis() + delay);
// Only schedule a job if before end date.
if (date.before(remoteJob.getStop())) {
// Update entity
remoteJob.setNext(date);
entityManager.merge(remoteJob);
// Create trigger
SimpleTrigger trigger = new SimpleTrigger(
"trigger" + jobDetail.getName().toString(),
Scheduler.DEFAULT_GROUP,
date,
null,
0,
0
);
// Schedule the job to run!
try {
jec.getScheduler().scheduleJob(jobDetail, trigger);
}
catch (SchedulerException e) {
e.printStackTrace();
}
}
else {
// Deactivate job
remoteJob.setActive(false);
entityManager.merge(remoteJob);
}
}
catch (Exception e) {
// >>> NPE: true == (null == entityManager)
log.error(e);
e.printStackTrace();
}
}
}
////////////////////////////////////////////////////////////////////
and persist the change.
>>>Using:
* jboss-5.1.0.GA (jboss-ejb3-plugin-1.0.19-installer.jar)
* Quartz quartz-1.7.3.jar
>>>Flow:
RemoteHome.scheduleJob() --> RemoteJobManager.scheduleJob(RemoteJob) --> RemoteJobListener.jobWasExecuted(...)
``
>>>Detail:
I want the job listener to reschedule the job and modify the RemoteJob entity.
Unfortunately, the injected @In EntityManager entityManager is null in the listener.
When I inject the log using @Logger, it is also null.
Why is injection failing in the listener?
Alternatively, I when I did a lookup on the entityManager by doing
Context ctx = new InitialContext();
em = (EntityManager) ctx.lookup(ENTITY_MANAGER);
it was not null. I think it failed when merge was called.
The exception led me to believe that I had to wrap the call in
a transaction. That did not work either.
I think I need to stay within the seam context to get it to work.
How should I proceed to reach my goal?
>>>Source code:
RemoteJobHome.java
///////////////////////////////////////////////////////////////////////////////
@Name("remoteJobHome")
public class RemoteJobHome extends EntityHome<RemoteJob> {
@Logger private Log log;
@RequestParameter Long remoteJobId;
@In RemoteJobManager manager;
@In(create = true)
HostHome hostHome;
public void setRemoteJobId(Long id) {
setId(id);
}
public Long getRemoteJobId() {
return (Long) getId();
}
@Override
protected RemoteJob createInstance() {
RemoteJob remoteJob = new RemoteJob();
return remoteJob;
}
public void load() {
if (isIdDefined()) {
wire();
}
}
public void wire() {
getInstance();
Host host = hostHome.getDefinedInstance();
if (host != null) {
getInstance().setHost(host);
}
}
public boolean isWired() {
return true;
}
public RemoteJob getDefinedInstance() {
return isIdDefined() ? getInstance() : null;
}
@Override
public Object getId() {
return remoteJobId;
}
// Schedule job
public String scheduleJob() throws Exception {
String result = persist();
RemoteJob remoteJob = getInstance();
manager.scheduleJob(remoteJob);
return result;
}
}
/////////////////////////////////////////////////////////////////
File: RemoteJobManager.java
/////////////////////////////////////////////////////////////////
@Name("manager")
@AutoCreate
public class RemoteJobManager {
@Logger Log log;
@In EntityManager entityManager;
public void scheduleJob(RemoteJob remoteJob) {
try {
InitialContext ctx = new InitialContext();
// Lookup scheduler
StdScheduler scheduler = (StdScheduler) ctx.lookup("Quartz");
// Create job
JobDetail jobDetail = new JobDetail(
remoteJob.getId().toString(),
Scheduler.DEFAULT_GROUP,
NoOpJob.class
);
SimpleTrigger trigger = new SimpleTrigger(
"trigger" + remoteJob.getId().toString(),
Scheduler.DEFAULT_GROUP,
remoteJob.getStart(),
null,
0,
0);
RemoteJobListener listener = new RemoteJobListener();
// Set up the listener
scheduler.addJobListener(listener);
// Make sure the listener is associated with the job
jobDetail.addJobListener(listener.getName());
// Schedule the job to run
scheduler.scheduleJob(jobDetail, trigger);
// Update entity
remoteJob.setNext(remoteJob.getStart());
entityManager.merge(remoteJob);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////
File: RemoteJobListener.java
/////////////////////////////////////////////////////////////////////
public class RemoteJobListener implements JobListener {
@In
EntityManager entityManager;
public void jobWasExecuted(JobExecutionContext jec, JobExecutionException jee) {
try {
JobDetail jobDetail = jec.getJobDetail();
RemoteJob remoteJob = entityManager.find(RemoteJob.class, new Long(jobDetail.getName()));
// Compute delay (ms)
Long delay = 10000;
Date date = new Date(System.currentTimeMillis() + delay);
// Only schedule a job if before end date.
if (date.before(remoteJob.getStop())) {
// Update entity
remoteJob.setNext(date);
entityManager.merge(remoteJob);
// Create trigger
SimpleTrigger trigger = new SimpleTrigger(
"trigger" + jobDetail.getName().toString(),
Scheduler.DEFAULT_GROUP,
date,
null,
0,
0
);
// Schedule the job to run!
try {
jec.getScheduler().scheduleJob(jobDetail, trigger);
}
catch (SchedulerException e) {
e.printStackTrace();
}
}
else {
// Deactivate job
remoteJob.setActive(false);
entityManager.merge(remoteJob);
}
}
catch (Exception e) {
// >>> NPE: true == (null == entityManager)
log.error(e);
e.printStackTrace();
}
}
}
////////////////////////////////////////////////////////////////////