Quartz 产生未处理的空指针异常
Quartz produces unhandled null pointer exception
因此,我在不同的 Spring 配置文件上设置了 2 个调度程序。当我 运行 Spring 调度程序时一切正常,但他们要我实现 Quartz。
这是一份工作class:
@Profile("quartz")
@Component
public class SampleJob implements Job {
@Autowired
private GetDataServiceQuartz getDataServiceQuartz;
public SampleJob() {
}
public SampleJob(GetDataServiceQuartz getDataServiceQuartz) {
this.getDataServiceQuartz = getDataServiceQuartz;
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
this.getDataServiceQuartz.storeData();
}
}
抛出错误:
org.quartz.SchedulerException: Job threw an unhandled exception.
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-2.2.1.jar:na]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.2.1.jar:na]
Caused by: java.lang.NullPointerException: null
at com.example.blockchaininfo.services.Quartz.SampleJob.execute(SampleJob.java:27) ~[classes/:na]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.2.1.jar:na]
... 1 common frames omitted
A nullPointerException
被扔到这个特定的行:
this.getDataServiceQuartz.storeData();
我一尝试打印 this.getDataServiceQuartz
它就打印 null
.
做所有后台工作的class:
@Slf4j
@Service
@Profile("quartz")
public class GetDataServiceQuartz{
constructorHere();
public void storeData(){
try {
String hashrateFromApi = this.getNetworkHashrateFromApi("http://public.turtlenode.io:11898/getinfo");
OffsetDateTime date = OffsetDateTime.now();
this.saveNetworkHashrateNewEntity(hashrateFromApi, date);
this.storePoolDataToDB(this.getPoolsListFromJson(), retrieveNetworkIdForPoolDefinition(date));
} catch (HttpServerErrorException e){
log.info("Network Server error e1: " + e);
} catch (ResourceAccessException e2){
log.info("Network resource access exception: " + e2);
} catch (IOException e3) {
log.info("" + e3);
} catch (InterruptedException e4){
log.info("" + e4);
}
}
...all other methods to acquire stuff.
和 Quartz 配置。
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent){
this.startQuartzScheduling();
}
public void startQuartzScheduling () {
JobDetail job = JobBuilder.newJob(SampleJob.class)
.withIdentity("dummyJobName", "group1").build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dummyTriggerName", "group1")
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(5).repeatForever())
.build();
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e){
log.info("" + e);
}
}
我错过了什么?如何正确注入一个应该安排其方法的 class?
我相信这会发生,因为 quartz JobBuilder
创建了您的 SampleJob
的新实例,而不是使用带有自动装配字段的已创建实例。因为它使用默认构造函数作为结果,所以你有空指针。
解决此问题的一个方法是将您的 GetDataServiceQuartz
放入调度程序上下文。
描述here
因此,要放置您的数据,您需要调用:
scheduler.getContext().put("getDataServiceQuartz", getDataServiceQuartz);
执行任务时:
SchedulerContext schedulerContext = jobExecutionContext.getScheduler().getContext();
schedulerContext.get("getDataServiceQuartz");
其他,在我看来更方便的方法是将其放入 JobDataMap
,可以从您的 SampleJob
:
获得
job.getJobDataMap().put("getDataServiceQuartz", getDataServiceQuartz);
执行任务时:
context.getJobDetail().getJobDataMap().get("getDataServiceQuartz")
可以找到完整示例 here。
因此,我在不同的 Spring 配置文件上设置了 2 个调度程序。当我 运行 Spring 调度程序时一切正常,但他们要我实现 Quartz。
这是一份工作class:
@Profile("quartz")
@Component
public class SampleJob implements Job {
@Autowired
private GetDataServiceQuartz getDataServiceQuartz;
public SampleJob() {
}
public SampleJob(GetDataServiceQuartz getDataServiceQuartz) {
this.getDataServiceQuartz = getDataServiceQuartz;
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
this.getDataServiceQuartz.storeData();
}
}
抛出错误:
org.quartz.SchedulerException: Job threw an unhandled exception.
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-2.2.1.jar:na]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.2.1.jar:na]
Caused by: java.lang.NullPointerException: null
at com.example.blockchaininfo.services.Quartz.SampleJob.execute(SampleJob.java:27) ~[classes/:na]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.2.1.jar:na]
... 1 common frames omitted
A nullPointerException
被扔到这个特定的行:
this.getDataServiceQuartz.storeData();
我一尝试打印 this.getDataServiceQuartz
它就打印 null
.
做所有后台工作的class:
@Slf4j
@Service
@Profile("quartz")
public class GetDataServiceQuartz{
constructorHere();
public void storeData(){
try {
String hashrateFromApi = this.getNetworkHashrateFromApi("http://public.turtlenode.io:11898/getinfo");
OffsetDateTime date = OffsetDateTime.now();
this.saveNetworkHashrateNewEntity(hashrateFromApi, date);
this.storePoolDataToDB(this.getPoolsListFromJson(), retrieveNetworkIdForPoolDefinition(date));
} catch (HttpServerErrorException e){
log.info("Network Server error e1: " + e);
} catch (ResourceAccessException e2){
log.info("Network resource access exception: " + e2);
} catch (IOException e3) {
log.info("" + e3);
} catch (InterruptedException e4){
log.info("" + e4);
}
}
...all other methods to acquire stuff.
和 Quartz 配置。
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent){
this.startQuartzScheduling();
}
public void startQuartzScheduling () {
JobDetail job = JobBuilder.newJob(SampleJob.class)
.withIdentity("dummyJobName", "group1").build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dummyTriggerName", "group1")
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(5).repeatForever())
.build();
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e){
log.info("" + e);
}
}
我错过了什么?如何正确注入一个应该安排其方法的 class?
我相信这会发生,因为 quartz JobBuilder
创建了您的 SampleJob
的新实例,而不是使用带有自动装配字段的已创建实例。因为它使用默认构造函数作为结果,所以你有空指针。
解决此问题的一个方法是将您的 GetDataServiceQuartz
放入调度程序上下文。
描述here
因此,要放置您的数据,您需要调用:
scheduler.getContext().put("getDataServiceQuartz", getDataServiceQuartz);
执行任务时:
SchedulerContext schedulerContext = jobExecutionContext.getScheduler().getContext();
schedulerContext.get("getDataServiceQuartz");
其他,在我看来更方便的方法是将其放入 JobDataMap
,可以从您的 SampleJob
:
job.getJobDataMap().put("getDataServiceQuartz", getDataServiceQuartz);
执行任务时:
context.getJobDetail().getJobDataMap().get("getDataServiceQuartz")
可以找到完整示例 here。