Jboss 6以上全局Filter加载顺序问题
既然知道问题所在那么现在的问题就是要找到之前调试Tomcat出问题的类和方法。根据我之前的记录,Tomcat 的Filter加载问题出现的位置大约是在“org.apache.catalina.core.ApplicationFilterRegistration.java的版本变动(修改74-78行、103-107行):Tomcat7.0.29的isMatchAfter判断的顺序反了。所以想办法把 顺序弄回去就行了。把context.addFilterMapBefore(filterMap);”。上一次我是改的catalina.jar的核心源码,所以在Jboss6目录搜索catalina.jar,发现没找到。搜catalina、Tomcat同样没找到对应的jar。估计是Jboss的开发人员把jar名改了,于是想写个递归遍历Jboss下所有的jar里面带有ApplicationFilterRegistration类或addFilterMapBefore方法的所有文件。
实现目录搜索jar和内容:
package jar; import java.io.File; import java.io.IOException; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.commons.io.IOUtils; public class Test { public static void getJarContent(File jarFile){ try { JarFile jf = new JarFile(jarFile); Enumeration<JarEntry> je = jf.entries(); while(je.hasMoreElements()){ JarEntry jar = je.nextElement(); if(!jar.isDirectory()){ String str = IOUtils.toString(jf.getInputStream(jar)); if(jarFile.toString().contains("ApplicationFilterRegistration")){ System.out.println("ApplicationFilterRegistration:"+jarFile.toString()+":"+jar.getName()); }else if(str.contains("addFilterMapBefore")){ System.out.println("addFilterMapBefore:"+jarFile.toString()+":"+jar.getName()); } } } jf.close(); } catch (IOException e) { e.printStackTrace(); } } public static void listFile(File f){ File[] files = f.listFiles(); for(File ff:files){ if(ff.isDirectory()){ listFile(ff); }else{ if(ff.toString().endsWith(".jar")){ getJarContent(ff); } } } } public static void main(String[] args) { listFile(new File("/Users/yz/Documents/install/jboss-6.0.0.Final/")); } }
一会儿功夫就完成了,输出结果:
addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/all/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/Context.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/all/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/core/ApplicationFilterConfig.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/all/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/core/StandardContext.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/default/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/Context.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/default/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/core/ApplicationFilterConfig.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/default/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/core/StandardContext.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/jbossweb-standalone/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/Context.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/jbossweb-standalone/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/core/ApplicationFilterConfig.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/jbossweb-standalone/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/core/StandardContext.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/standard/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/Context.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/standard/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/core/ApplicationFilterConfig.class addFilterMapBefore:/Users/yz/Documents/install/jboss-6.0.0.Final/server/standard/deploy/jbossweb.sar/jbossweb.jar:org/apache/catalina/core/StandardContext.class
搜索并未发现有ApplicationFilterRegistration这个类,Jboss的哥们又调皮了。虽然搜索结果出现了很多其实也就一个jar,Jboss默认配置有多个实例只看default目录下的就行了。
反编译jbossweb.jar,找到对应的:
Context.class、ApplicationFilterConfig.class、StandardContext.class这三个类
问题已经一目了然了,明显是采用了Tomcat7.0.29以上版本的Filter写法。Tomcat7.0.30开始if和else被调换了个顺序,导致加载全局Filter的时候会有一个BUG。只有在应用层404的情况下Filter才会走到全局拦截的Filter类里面去。解决办法当然是把if和else的内容换回来咯。
Tomcat7.0.29和7.0.30变更内容:
无奈,╮(╯_╰)╭。