shiro与quartz2集成报错解决方案

错误描述

在shiro实现权限控制下集成quartz2;集成成功后发现定时任务在执行是报如下错误:
这里写图片描述

2018-01-24 15:35:23 [ scheduler_Worker-1:2076922 ] - [ ERROR ] Job (job_2480F7EA027E461C9ED2E06B8555FF8D.job_7D928929B8694450B39FE67740159FDC threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.]
    at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.
    at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
    at org.apache.shiro.subject.Subject$Builder.<init>(Subject.java:627)
    at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:56)

解决方法

然后查询资料发现shiro实现是针对quartz1.6版本的实现(详细源码请查看QuartzSessionValidationScheduler),在quartz2.2.1中,SimppleTrigger为接口,所以无法实例化;网上好多方法都是进行重写,参考:http://www.hillfly.com/2017/178.html
由于定时任务模块已经成形不想修改太多,后面查看报错源头在org.apache.shiro.SecurityUtils:

这里写图片描述

没有找到securityManager实例对象,在源码里可以发现获取securityManager调用了ThreadContext中的方法,在追踪ThreadContext源码发现其实就是用map来存储securityManager对象。securityManager对象为shiro为安全管理器通过在配置文件中通过spring注入
这里写图片描述

然后利用spring特性就做出来大胆的尝试:在定时任务执行时在execute方法中直接实例化了securityManager在利用ThreadContext方法存入securityManager对象;

这里写图片描述
这样就不会报错了,但是不是知道这样实例securityManager的方法对框架什么影响还有待探究

2018/1/26 问题补充

最后发现以上修改方式,当程序运行一段时间后报出了一下错误

org.apache.shiro.session.UnknownSessionException: There is no session with id [bae5ddd9-1745-4667-98d2-bb10c10f7623]
    at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:170)
    at com.eims.modules.rbac.security.session.SessionDao.doReadSession(SessionDao.java:34)

问题最后追踪发现 在每次执行完定时任务后回去更新定时任务自定义任务信息,用到了更新UpdateUser;在获取UpdateUser是用到了org.apache.shiro.session.Session

    /**
     * 
     * @Title: getSession
     * @Description: TODO 获取当前的ession,R如果为空创建一个新的Session 
     * @return Session 返回类型
     * @throws
     */
    public static Session getSession(){
        try{
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession(false);
            if (session == null){
                session = subject.getSession();
            }
            if (session != null){
                return session;
            }
        }catch (InvalidSessionException e){

        }
        return null;
    }

最终解决方案:

去掉了之前的securityManager的添加;最后修改UpdateUser设置为固定值,不用session就没有出现过错误了

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值