Reputation: 555
How can I force the creation or injection of my EJB (with JPA Entitymanager) in this code?
The problem is that jc.doStuff() runs fine for one time in @PostConstruct because the EJB is actice, but Quartz is calling execute() and the EJB is of course not injected. jc.doStuff throws null pointer exception because of the EJB.
What can I do? How can I inject the EJB that execute has access to it too?
Thank you for your help!
@ManagedBean
@ApplicationScoped
public class JobDatasource implements Job {
@EJB
JobContent jc;
private String TEXT = "V1";
public JobDatasource() {
System.out.println("Job Bean created");
}
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
jc.doStuff();
}
@PostConstruct
public void startJob() throws SchedulerException {
System.out.println("Und los gehts!");
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
JobDetail jobdataSourceCheck = JobBuilder.newJob(JobDatasource.class)
.withIdentity("DataSourceCheck", "group1").build();
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(
simpleSchedule().withIntervalInSeconds(10)
.repeatForever()).build();
sched.scheduleJob(jobdataSourceCheck, trigger);
jc.doStuff();
sched.start();
}
public String getTEXT() {
return TEXT;
}
public void setTEXT(String tEXT) {
TEXT = tEXT;
}
}
@Stateless
public class JobContent {
@EJB
ITestDataDao dao;
public void doStuff() {
Set<TestData> testdata = createTestData();
for (TestData td : testdata) {
dao.saveData(td);
}
}
private Set<TestData> createTestData() {
Set<TestData> testData = new HashSet<TestData>();
for (int i = 0; i < 500; i++) {
TestData td = new TestData();
td.setRandomText("TESTDATA");
testData.add(td);
}
return testData;
}
}
Upvotes: 1
Views: 917
Reputation: 555
On JBoss is was even easier
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
Context ctx = null;
try {
ctx = new InitialContext();
IJobContent exampleBean = (IJobContent) ctx
.lookup("java:global/DSMonitor/jobcontent!de.bva.dsmonitor.job.IJobContent");
exampleBean.doStuff();
} catch (NamingException e) {
System.err.println("EJB JobContent not found!");
e.printStackTrace();
}
}
Upvotes: 0
Reputation: 1912
It will not be injected because you are using Quartz and not EJB to start the task.
You could do two things:
Use RMI to get your EJB. You could use the service locator pattern and apply it in the task:
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
props.put(Context.PROVIDER_URL,"t3://127.0.0.1:7001");
Context ctx = new InitialContext(props);
Object ref = ctx.lookup("HelloBean#org.acme.Hello");
Hello h = (Hello)PortableRemoteObject.narrow(ref, Hello.class);
String result;
result = h.sayHello();
System.out.println(result);
h.helloWait();
result = h.sayHello();
System.out.println(result)
// Grabbed from here: http://www.coderanch.com/t/443061/EJB-JEE/java/world-EJB
You could use EJB Timer to start your task and not the Quartz.
@Schedule(dayOfWeek="Mon,Wed", hour="8", minute="30") public void yourTask() { System.out.println("It alive"); }
It is possible to say that the option one could be applied to any EJB version, but you will need to use Lookup and take care with the EJB Names. With the option two you could use EJB to start your task and have access to all EJB features, but you will need EJB 3.1.
Upvotes: 2