Struts2动态Web项目转Maven项目后可执行mvn clean install但启动时出现ClassNotFoundException异常求助
嘿,我碰到过好多次这种Struts2转Maven后WebSphere启动报错的情况,你遇到的java.lang.ClassNotFoundException:org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter,看起来WAR包明明有对应JAR,但服务器就是找不到类,大概率是这几个原因导致的,咱们一步步排查:
1. 先检查Struts2依赖的Scope配置
你在pom.xml里加的Struts2核心依赖(比如struts2-core),要是不小心把scope设成了provided或者test,那麻烦就来了——虽然你说WAR包里有JAR,但provided会告诉Maven“这个类由服务器提供”,可WebSphere本身根本没这个类啊!
- 打开pom.xml,找到Struts2相关依赖,确保scope是默认的
compile(不用显式写,默认就是),别加provided或test。举个正确的配置例子:
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.30</version> <!-- 这里别乱加scope! --> </dependency>
2. 确认Struts2版本和过滤器路径匹配
划重点:org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter这个类是Struts2.5及以上版本才有的!2.5之前的版本,过滤器的包路径是org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,差了个ng。
- 先看你pom.xml里的Struts2版本,再对照web.xml里的过滤器配置:
- 如果用的是2.5+,web.xml里的配置就得是上面报错的那个路径;
- 如果依赖的是旧版本,要么把web.xml里的过滤器类改成旧路径,要么直接把Struts2升级到2.5+(更推荐后者,旧版本有安全漏洞)。
3. 排查Maven依赖冲突
有时候你加了一堆依赖,说不定某个间接依赖偷偷带进来了旧版本的Struts2 JAR,类加载的时候优先加载了旧版本,自然找不到新的过滤器类。
- 跑个
mvn dependency:tree命令,看看依赖树里有没有多个版本的Struts2相关JAR。要是发现有旧版本被间接依赖进来,就在对应的依赖里把它排除掉:
<dependency> <groupId>某个依赖的groupId</groupId> <artifactId>某个依赖的artifactId</artifactId> <version>xxx</version> <exclusions> <exclusion> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> </exclusion> </exclusions> </dependency>
4. 调整WebSphere的类加载策略
WebSphere默认的类加载顺序是“父类加载器优先”,也就是说先加载服务器自带的类,再加载你项目里的。如果服务器本身装了旧版本的Struts2,那肯定会优先用服务器的,你项目里的新JAR就白搭了。
- 登录WebSphere控制台,找到你的应用:
- 进入应用的「类加载和更新检测」设置;
- 把类加载顺序改成「应用程序类加载器优先」(先加载你项目里的JAR);
- 保存配置后重启应用试试。
5. 最后验证WAR包的JAR完整性
虽然你说WAR包里的JAR和原WEB-INF/lib一致,但还是得确认一下:
- 解压生成的WAR包,打开
WEB-INF/lib下的struts2-core-x.x.x.jar,看看里面有没有org/apache/struts2/dispatcher/filter/StrutsPrepareAndExecuteFilter.class这个文件。 - 如果没有,说明你依赖配置错了,要么没引对核心JAR,要么版本不对,得重新调整pom.xml。
按照上面的步骤挨个排查,应该就能解决这个问题了。
内容的提问来源于stack exchange,提问作者Gopal Reddy

