工作中需要解决一些servlet容器类加载器的问题,尤其是jboss 4.x系列,比方说log4j版本冲突需要靠更改配置项java2classloadingcompliance,usejbosswebloader;ear包部署,出现nosuchmethoderror,nosuchfielderror,noclassdeffounderror等(二进制兼容错误)需要进行类隔离(在 jvm加上-xx:+traceclassloading -xx:+traceclassunloading分析完类的加载卸载verbose)等。除此之外,还有一种classloader问题比较常见。即:如果类库提供了
spi 接口,并且利用线程上下文类加载器来加载 spi 实现的 java 类,有可能会找不到 java 类。如果出现了 noclassdeffounderror异常(初始类加载器,定义类加载器问题),则可以先检查当前线程的上下文类加载器是否正确。通过 thread.currentthread().getcontextclassloader()就可以得到该类加载器。该类加载器应该是该模块对应的类加载器。如果不是的话,可以首先通过 class.getclassloader()来得到模块对应的类加载器,再通过
thread.currentthread().setcontextclassloader()来设置当前线程的上下文类加载器。关于上下文加载器,一个显著的使用场景是javax.xml.parsers.documentbuilderfactory类中的newinstance方法,跟进去后代码具体如下:
最后,将自己曾经参考过的文献资料分享给大家,希望能对大家有所帮助。
8. http://javarevisited.blogspot.com/2011/06/noclassdeffounderror-exception-in.html
9. http://www.artima.com/insidejvm/blurb.html
10. http://articles.qos.ch/classloader.html