Apache POI 3.9在JBOSS 4.2.2GA可用但JBOSS 6.0.0 Final报错求助
这个问题我之前在项目迁移时也碰到过,核心原因是JBoss 6的模块化类加载机制和JBoss 4.2.2的类加载逻辑差异,导致POI依赖的关键类无法被正确加载。具体来说,org.apache.poi.POIXMLTypeLoader属于poi-ooxml-3.9-20121203.jar,但JBoss 6自带的库(比如xmlbeans)或者类加载优先级问题,让应用找不到这个类。
下面是几个经过验证的可行解决方案:
1. 调整应用类加载优先级,优先加载WEB-INF/lib中的Jar
JBoss 6默认采用父类加载器优先策略,这会导致容器自带的库覆盖你应用中的POI依赖。你可以通过jboss-web.xml修改类加载顺序:
在WEB-INF目录下创建(或修改)jboss-web.xml,添加以下内容:
<jboss-web> <class-loading java2ClassLoadingCompliance="false"> <loader-repository> com.yourcompany:archive=your-web-app-name.war <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository> </class-loading> </jboss-web>
替换com.yourcompany和your-web-app-name.war为你自己的应用信息,这样应用会优先加载自身lib目录下的Jar,避免容器库的干扰。
2. 排除JBoss 6自带的冲突模块
JBoss 6自带了xmlbeans模块,而你使用的是POI 3.9依赖的xmlbeans-2.3.0,版本不一致会引发类加载冲突。可以通过jboss-deployment-structure.xml排除容器自带的xmlbeans:
在WEB-INF或META-INF目录下创建jboss-deployment-structure.xml,内容如下:
<jboss-deployment-structure> <deployment> <exclusions> <module name="org.apache.xmlbeans" /> </exclusions> </deployment> </jboss-deployment-structure>
这样容器就不会加载自带的xmlbeans,转而使用你应用WEB-INF/lib中的xmlbeans-2.3.0.jar。
3. 再次确认依赖完整性
最后检查你的WEB-INF/lib目录,确保以下Jar包都存在且版本正确:
poi-3.9-20121203.jarpoi-ooxml-3.9-20121203.jarpoi-ooxml-schemas-3.9.jarpoi-scratchpad-3.9.jarxmlbeans-2.3.0.jar
如果有缺失,补充完整后重新部署即可。
至于为什么JBoss 4.2.2运行正常?因为JBoss 4采用传统的父优先类加载,没有模块化隔离,你的应用依赖可以直接被加载;而JBoss 6引入了模块系统,容器会管理自身的库,很容易和应用依赖产生版本冲突。
内容的提问来源于stack exchange,提问作者venkat

