问题描述
Unexpected exception occurred invoking async method: public void com.gw.data.activiti.service.impl.ActivitiBusinessServiceImpl.updateBusinessData(java.lang.String)
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.
问题分析及解决
项目使用的是shiro,然后我在业务代码调用了**@Async异步方法updateBusinessData
,然后updateBusinessData
方法中又调用了间接使用shiro框架的SecurityUtils.getSubject();,从而导致了异常。估计就是异步带来的问题,把@Async**删除就可以正常运行了
业务代码
ActivitiServiceImpl
@Service
@Slf4j
public class ActivitiServiceImpl implements ActivitiService {
@Lazy
@Autowired
private ActivitiBusinessService activitiBusinessService;
/**
* 通过流程实例id获取当前任务节点(当前任务节点的任务id和任务名称)
*
* @param processInstanceId
* @return
*/
public CurrentTaskVO getCurrentTaskByProcessInstId(String processInstanceId) {
// 在@Async异步方法的里调用这个会报错
String tenantId = sysUtil.getTenantId();
//...
}
/**
* 完成任务
*/
@Override
public void completeTask(String taskId, String comment) {
// 更新业务数据
activitiBusinessService.updateBusinessData(task.getProcessInstanceId());
}
}
ActivitiBusinessServiceImpl
@Service
@EnableAsync
public class ActivitiBusinessServiceImpl implements ActivitiBusinessService {
@Autowired
private ActivitiServiceImpl activitiServiceImpl;
//@Async
@Override
public void updateBusinessData(String processInstanceId) {
// 使用@Async的话这里会异常
CurrentTaskVO currentTaskVO = activitiServiceImpl.getCurrentTaskByProcessInstId(processInstanceId);
}
}
SysUtil
/**
* 系统相关工具类
*/
@Service
public class SysUtil {
@Autowired
private SysDeptDao sysDeptDao;
/**
* 获取当前用户信息
*/
public UserLoginInfo getUserLoginInfo() {
Subject subject = SecurityUtils.getSubject();
UserLoginInfo userInfo = (UserLoginInfo) subject.getPrincipal();
return userInfo;
}
/**
* 通过当前用户获取tenantId
* @return
*/
public String getTenantId(){
UserLoginInfo userLoginInfo = getUserLoginInfo();
return getTenantId(userLoginInfo.getDeptId());
}
/**
* 向上查找有tenantId的公司
* @return
*/
private String getTenantId(Long deptId){
SysDept sysDept = sysDeptDao.getSysDeptById(deptId);
if (sysDept.getTenantId() == 1) {
return String.valueOf(sysDept.getId());
}
return getTenantId(sysDept.getId());
}
}
参考文献
这里有一些关于shiro对于以上报错的解决连接
Shiro报错:No SecurityManager accessible to the calling code, either bound to the…的几种情况