struts2仿佛是很久远的事情了,但我现在开发的项目也是好几年前开始的,所以还是使用了struts2。
今天遇到一个很奇怪的问题,把一个项目依赖的jar升级后,项目启动后首页访问不了。。。
开始怀疑是不是jar中有配置文件,干扰了struts2的配置
但jar中并没有可疑的配置文件。。。
经过反复debug,发现jar升级前后,struts2中加载Action的数量不同。
最后把问题定位到了org.apache.struts2.convention.PackageBasedActionConfigBuilder
private UrlSet buildUrlSet(List<URL> resourceUrls) throws IOException {
ClassLoaderInterface classLoaderInterface = this.getClassLoaderInterface();
UrlSet urlSet = new UrlSet(resourceUrls);
urlSet = urlSet.include(new UrlSet(classLoaderInterface, this.fileProtocols));
if (this.excludeParentClassLoader) {
ClassLoaderInterface parent = classLoaderInterface.getParent();
if (parent != null && this.isReloadEnabled()) {
parent = parent.getParent();
}
if (parent != null) {
urlSet = urlSet.exclude(parent);
}
try {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
urlSet = urlSet.exclude(new ClassLoaderInterfaceDelegate(systemClassLoader.getParent()));
} catch (SecurityException var12) {
...
}
}
...
}
在该方法中,struts2通过当前classLoader解析url,然后struts2会扫描这些url,加载对应的Action。
这里有个excludeParentClassLoader操作,struts2会解析parent classLoader的url,并剔除它们。
而升级后的jar因为添加了一个classLoader, 并且struts2解析该classLoader和它parent的url是相同,所以导致url都被剔除了,struts2没有加载到Action。
解决方案:
PackageBasedActionConfigBuilder.excludeParentClassLoader是可以配置的。
在struts2配置文件中添加:
<constant name="struts.convention.exclude.parentClassLoader" value="false" />
网友评论