应用关闭时出现InjectionException,如何消除日志中的该错误?
应用关闭时出现InjectionException,如何消除日志中的该错误?
我之前也碰到过一模一样的问题!E4在应用 shutdown 阶段的DI清理逻辑确实有点“较真”——你的ModelTreeLabelProvider注入了IWorkbench,但当应用要关闭时,IWorkbench实例已经被销毁回收了,DI容器在尝试对这个LabelProvider执行uninject操作时,找不到有效的IWorkbench实例,就抛出了这个异常。虽然完全不影响功能,但日志里堆着这么个错误确实看着闹心。
给你几个亲测有效的解决办法,按推荐程度排序:
方法一:给注入的IWorkbench添加@Optional注解
这是最直接的解决方案,告诉DI容器这个依赖是“可选”的——就算uninject阶段找不到IWorkbench实例,也别抛出异常。修改后的代码如下:
public class ModelTreeLabelProvider implements ILabelProvider { @Inject @Optional IWorkbench workbench; @Override public Image getImage(Object element) { // 一定要加null判断!防止workbench被置空后调用方法触发NPE if (workbench == null) { return null; // 或者返回你自己的默认占位图片 } return workbench.getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); } [...] }
原理很简单:@Optional标记会让DI容器在处理依赖注入/解除注入时,忽略“找不到实例”的情况,直接跳过,自然就不会打错误日志了。
方法二:直接注入你真正需要的服务,绕开IWorkbench
你实际用到的是ISharedImages,没必要通过IWorkbench中转获取,直接注入ISharedImages会更稳妥,也能减少和IWorkbench强绑定带来的生命周期问题:
public class ModelTreeLabelProvider implements ILabelProvider { @Inject @Optional ISharedImages sharedImages; @Override public Image getImage(Object element) { if (sharedImages == null) { return null; } return sharedImages.getImage(ISharedImages.IMG_OBJ_ELEMENT); } [...] }
这个方案的好处是,你只依赖你真正需要的服务,减少了不必要的耦合,同时同样用@Optional避免uninject时的异常。
方法三:通过生命周期注解手动清理依赖
让你的LabelProvider实现@PreDestroy注解的方法,在DI容器开始uninject之前手动置空依赖,这样容器处理时就不会找不到实例了:
public class ModelTreeLabelProvider implements ILabelProvider { @Inject IWorkbench workbench; @Override public Image getImage(Object element) { if (workbench == null) { return null; } return workbench.getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT); } @PreDestroy public void cleanUp() { // 在销毁前手动置空,让uninject阶段找不到这个字段的有效实例时不会报错 this.workbench = null; } [...] }
这个方案稍微麻烦一点,但适合你不想用@Optional的场景。
总结一下,最推荐方法一,改动最小,效果直接,完全能解决日志里的这个异常问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

