1.问题:
在Tomcat启动时会在struts2初始化时提示 org.apache.struts2.util.fs.JBossFileManager DEBUG Cannot load [org.jboss.vfs.VirtualFile] class, not a JBoss 7!
整个启动过程中大概有468条类似信息,按道理来说 tomcat启动不应该报非jboss,而且即使他采用策略模式也不应该报这么多次。
2.问题原因:
struts2从大概2.3.7版本后调整了FileManager类结果,将JBoss的逻辑分离出来,在容器初始化时如果没有用户自定义的FileManager,会默认使用JbossFileManager,
。而FileManager会用来加载xml配置文件和action中的配置信息。(OsgiConfigurationProvider类中),action中的配置这块是给super中的struts config用的。
这里用来加载xml配置文件
这里用来加载action类
这是最终加载action类的逻辑
每次要使用FileManager,容器中只有两个 system和jboss,因此会判断是否是jboss环境,不是的话采用system,因此在OSGi环境下查找多个配置文件和action类便出现了很多次判断是否是jboss。
再验证问题的过程中,发现以上逻辑走了两遍,因为我们在web.xml中配了StrutsListener和StrutsPrepareFilter,这两个都是struts入口,都会初始化dispatcher,加载xml配置和action中的配置。
3.解决方案:
A.自定义一个FileManager和FileManagerFactory,继承默认实现,创建缓存,不再重复生成FileManager.并在Struts.xml和web.xml中配置参数,使其不再使用JBossFileManager.
B.上一步只能解决StrutsPrepareFilter初始化Dispatcher过程,而StrutsListener初始化Dispatcher时是不支持自定义参数的,因此还会使用默认的JBossFileManager,因此考虑去掉此Listener,这样就不会
重复初始化Dispatcher过程了,也会加快系统的启动过程。
查询资料StrutsListener是用来向其他servlet listener提供struts config信息的,比如 sitemesh和osgi,否则 推荐使用StrutsPrepareAndExecuteFilter。
The preferred way to use Struts is as a filter via the
* {@link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter} and its variants.
* This might be useful if Struts config information is needed from other servlet listeners, like
* Sitemesh or OSGi
目前去掉此strutsListener后尚未发现有影响。