前几天在写一个拦截器的时候,使用到了StringUtils这个工具类,但是使用postman模拟请求的时候,dispatcherServlet 一直报异常。断点调试,之前的语句一直没有问题,但是一旦调用StringUtils.blank()方法,就直接跳到异常处理模块。当时非常惊讶,这条语句本身是没有加try catch块处理的,为什么会直接跳到dispatcherServlet 的异常处理模块。疑惑之下,我在junit 单元测试中使用了该方法,丝毫没有问题,当时就感觉有点玄学。
@Test public void testfun2(){ String str = null; if(StringUtils.isBlank(str)){ System.out.println("null"); }else{ System.out.println("not null"); } }
后来实在想不出为什么了,就老老实实地完整地调试了一遍。在catch块中发现了java.lang.NoClassDefFoundError这个错误,找不到定义的类,可是编译没有任何错误,我也能看到这个类的代码呀,一脸茫然,于是赶紧搜资料,才发现了其中的原因:
1、NoClassDefFoundError错误的发生,是因为Java虚拟机在编译时能找到合适的类,而在运行时不能找到合适的类导致的错误。
2、在J2EE的环境下工作时得到NoClassDefFoundError的异常,而且对应的错误的类是确实存在的,这说明这个类对于类加载器来说,可能是不可见的。
既然类对于类加载器来说可能是不可见的,那么简单暴力的方法,根据tomcat的类加载机制,可以直接将对应的jar包添加到WEB-INF下的lib下。测试了一下,没有报异常了。
其中参考文章链接:https://blog.csdn.net/jamesjxin/article/details/46606307,文章对NoClassDefFoundError和ClassNotFoundException的区别进行了讲解,并详细讲解了NoClassDefFoundError的原因以及其解决方案。
但是依然有一个疑问,为什么在junit 中运行该类没有问题,在Spring启动运行的时候却会出问题呢?