1、研究了quartz几天,问题发现不少,在全部配置好spring、quartz和mysql集群后,最后卡在一个空指针问题上
- java.lang.reflect.InvocationTargetException
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
- at java.lang.reflect.Method.invoke(Method.java:597)
- at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:276)
- at com.telek.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.execute(MethodInvokingJobDetailFactoryBean.java:555)
- at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
- at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:534)
- Caused by: java.lang.NullPointerException
2、简要说下原因与解决过程
首先,在集群中我们是通过数据库来进行管理的,所以我们的定时任务与触发器规则都需要以流的形式序列化到数据库中,这样需要定时的类必须实现序列化接口Serializable,其中有的属性相关的类也要实现序列化接口,所以一旦有与数据库交互的操作并且通过spring进行托管注入管理了,在service、dao都需要实现序列化接口,但是我全部做好以后还是会出现这个异常问题,最后饶了一个大圈终于发现原来我的Dao层的类虽然实现了序列化接口,但是它继承的HibernateDaoSupport中的HibernateTemplate并没有实现序列化接口,所以在此处必须换一种形式:HibernateTemplate没有实现序列化接口,而SessionFactory是实现序列化接口的,在ManagerDao注入SessionFactory,通过SessionFactory获取HibernateTemplate,也就是下面这种形式
- public class ManagerDaoImpl implements ManagerDao implements Serializable{
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private SessionFactory sessionFactory;
- public void saveManager(Manager manager) {
- HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
- hibernateTemplate.save(manager);
- }
- public SessionFactory getSessionFactory() {
- return sessionFactory;
- }
- public void setSessionFactory(SessionFactory sessionFactory) {
- this.sessionFactory = sessionFactory;
- }
- }
3、问题解决了,但是同时新的问题产生了,在集群服务宕机的情况下,报出了sessionFactory为null的错误,最后解决:在spring配置文件中加一句话(具体的话忘记了,想起来了再回来补)。
4、其实这种方式个人认为不理想,因为这样只要用到定时器的部分都需要去修改源代码了,这样高耦合度在开发中是不可取的。所以后面经过研究思考,有了另外一种方式,将定时器与数据库的交互操作分离开来,也就是一开始就将需要的bean放在bean池中,在具体调用的方法中再从bean池中获取,这样就做到了定时器与数据库交互的分离设计,而对于开发人员来说要做的也只是配置一些简单的定时操作即可。