11package io .dongtai .iast .core .handler .hookpoint .api ;
22
33import io .dongtai .iast .common .constants .AgentConstant ;
4+ import io .dongtai .iast .core .handler .hookpoint .IastClassLoader ;
45import io .dongtai .iast .core .handler .hookpoint .controller .impl .HttpImpl ;
56import io .dongtai .log .DongTaiLog ;
67
8+ import java .lang .reflect .InvocationTargetException ;
79import java .lang .reflect .Method ;
10+ import java .net .URL ;
811
912/**
1013 * @author CC11001100
@@ -22,7 +25,7 @@ public static void gather(Object applicationContext) {
2225 return ;
2326 }
2427 isStarted = true ;
25-
28+
2629 new SpringGatherApiThread (applicationContext ).start ();
2730 }
2831
@@ -36,15 +39,40 @@ public SpringGatherApiThread(Object applicationContext) {
3639 @ Override
3740 public void run () {
3841 try {
39- Class <?> proxyClass = HttpImpl .getClassLoader ().loadClass ("io.dongtai.iast.api.gather.spring.extractor.SpringMVCApiExtractor" );
40- Method getAPI = proxyClass .getDeclaredMethod ("run" , Object .class );
41- Object openApi = getAPI .invoke (null , applicationContext );
42- report (openApi , FRAMEWORK_NAME );
42+ this .runWithClassLoader (HttpImpl .getClassLoader ());
4343 } catch (NoClassDefFoundError e ) {
4444 DongTaiLog .debug ("SpringGatherApiThread NoClassDefFoundError " , e );
45+
46+ // 让它继承当前线程的上下文,在Tomcat这种破坏双亲委派的场景作为fallback
47+ // 比如在Tomcat下可能Request是一个ClassLoader,可能Context中的Spring类被另一个单独的ParallelWebappClassLoader所加载
48+ try {
49+ IastClassLoader iastClassLoader = new IastClassLoader (
50+ Thread .currentThread ().getContextClassLoader (),
51+ new URL []{HttpImpl .IAST_REQUEST_JAR_PACKAGE .toURI ().toURL ()});
52+ this .runWithClassLoader (iastClassLoader );
53+ } catch (Throwable e2 ) {
54+ DongTaiLog .debug ("SpringGatherApiThread NoClassDefFoundError 002" , e2 );
55+ }
56+
4557 } catch (Throwable e ) {
4658 DongTaiLog .error ("SpringGatherApiThread.reflection failed" , e );
4759 }
4860 }
4961
62+ /**
63+ * 使用给定的ClassLoader加载收集API
64+ *
65+ * @param classLoader
66+ * @throws NoSuchMethodException
67+ * @throws InvocationTargetException
68+ * @throws IllegalAccessException
69+ * @throws ClassNotFoundException
70+ */
71+ private void runWithClassLoader (ClassLoader classLoader ) throws NoSuchMethodException , InvocationTargetException , IllegalAccessException , ClassNotFoundException {
72+ Class <?> proxyClass = classLoader .loadClass ("io.dongtai.iast.api.gather.spring.extractor.SpringMVCApiExtractor" );
73+ Method getAPI = proxyClass .getDeclaredMethod ("run" , Object .class );
74+ Object openApi = getAPI .invoke (null , applicationContext );
75+ report (openApi , FRAMEWORK_NAME );
76+ }
77+
5078}
0 commit comments