Как я могу заставить создание или вложение моего EJB (с JPA Entitymanager) в этот код?
Проблема в том, что jc.doStuff() работает отлично в течение одного раза в @PostConstruct, потому что EJB является actice, но Quartz вызывает execute(), и EJB, конечно, не вводится. jc.doStuff выбрасывает исключение нулевого указателя из-за EJB.
Что я могу сделать? Как я могу вставить EJB, который имеет доступ к нему?
Спасибо за помощь!
@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;
}
}
На JBoss было еще проще
@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();
}
}
Он не будет вводиться, потому что вы используете Quartz, а не EJB, чтобы запустить задачу.
Вы могли бы сделать две вещи:
Используйте RMI для получения EJB. Вы можете использовать шаблон локатора службы и применить его в задаче:
Свойства props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
props.put(Context.PROVIDER_URL, "t3://127.0.0.1: 7001");
Контекст ctx = новый InitialContext (реквизит);
Object ref = ctx.lookup("HelloBean # org.acme.Hello");
Привет h = (Hello) PortableRemoteObject.narrow(ref, Hello.class);
Строковый результат;
result = h.sayHello();
System.out.println (результат);
h.helloWait();
result = h.sayHello();
System.out.println (результат)
//Схвачено отсюда: http://www.coderanch.com/t/443061/EJB-JEE/java/world-EJB
Вы можете использовать EJB Timer для запуска своей задачи, а не Quartz.
@Schedule (dayOfWeek = "Mon, Wed", hour = "8", минута = "30") public void yourTask() {System.out.println("Он жив"); } }
Можно сказать, что этот вариант можно применить к любой версии EJB, но вам нужно будет использовать Lookup и позаботиться об именах EJB. С помощью опции два вы можете использовать EJB для запуска своей задачи и доступа ко всем функциям EJB, но вам понадобится EJB 3.1.