diff --git a/docs/zh/document/developer-guide/bytecode-enhancement.md b/docs/zh/document/developer-guide/bytecode-enhancement.md index e01822156..5ecf658ca 100644 --- a/docs/zh/document/developer-guide/bytecode-enhancement.md +++ b/docs/zh/document/developer-guide/bytecode-enhancement.md @@ -207,14 +207,15 @@ 更多方法匹配方式可以参考[byte-buddy](https://javadoc.io/doc/net.bytebuddy/byte-buddy/latest/net/bytebuddy/matcher/ElementMatchers.html)中含`MethodDescription`泛型的方法。 ### 原生类增强 -增强原生类和增强普通类在增强定义和拦截器编写上没有什么区别,但是还是希望插件开发者尽量少地对原生类进行增强,原因有三: +增强原生类和增强普通类在增强定义和拦截器编写上没有什么区别,但还是希望插件开发者尽量少地对原生类进行增强,原因有二: -- 对原生类的增强往往是发散的,对他们增强很可能会对其他插件或宿主功能造成影响。 -- 对原生类的增强逻辑,将使用反射的方式调用系统类加载器中的拦截器方法。由于*Java*重定义*Class*的限制,每次调用被增强方法的时候,都会进行反射处理的逻辑,这将极大影响被增强方法的性能。 -- 对原生类的增强过程中,涉及到使用**Advice模板类**生成动态拦截类。对于每个被增强的原生类方法,都会动态生成一个,他们将被系统类加载器加载。如果不加限制的增强原生类,加载动态类也会成为启动过程中不小的负担。 +- 对原生类进行增强可能导致不可预知的错误。因为原生类在开发过程中被广泛使用,对它们增强后可能会对使用到该类的其他插件或宿主功能造成影响。 +- 对Sermant增强过程中使用的个别原生类方法进行增强可能会出现类循环依赖错误。比如Sermant类加载器在加载类的过程中会使用`java.net.URL`类,如果在插件中对URL类的构造方法进行增强,宿主应用挂载Agent启动后JVM抛出`ClassCircularityError`错误。 综上,[**Sermant**核心功能模块](https://github.com/huaweicloud/Sermant/tree/develop/sermant-agentcore/sermant-agentcore-core)中提供对*Java*原生类增强的能力,但不建议不加限制地对他们进行增强,如果有多个增强点可选,优先考虑增强普通类。 +> 我们在FAQ中的[Sermant框架常见问题](../faq/framework.md)里列举了已知的[Sermant不支持增强的原生类](../faq/framework.md#sermant不支持对哪些原生类的增强)。 + ## 拦截器 拦截器用于定义在对被增强类的方法进行字节码增强时的前置、后置及处理异常时的增强逻辑: - [Interceptor](https://github.com/huaweicloud/Sermant/blob/develop/sermant-agentcore/sermant-agentcore-god/src/main/java/com/huaweicloud/sermant/core/plugin/agent/interceptor/Interceptor.java): 拦截器接口,其中包含三个方法: diff --git a/docs/zh/document/faq/framework.md b/docs/zh/document/faq/framework.md index d5d83c199..a82165efb 100644 --- a/docs/zh/document/faq/framework.md +++ b/docs/zh/document/faq/framework.md @@ -40,4 +40,12 @@ > 注: > 1、不要用-D参数去修改Sermant的配置信息,否则会同时修改所有Sermant。 > 2、使用动态配置时,保证不同Sermant的group信息不一致,或者使用不一样的配置中心。否则所有Sermant会公用同一个动态配置。 -> 3、如果不同Sermant加载同样的插件时,请按照步骤一的方式将插件的类路径进行重定向,防止冲突。 \ No newline at end of file +> 3、如果不同Sermant加载同样的插件时,请按照步骤一的方式将插件的类路径进行重定向,防止冲突。 + +## Sermant不支持对哪些原生类的增强 +对Sermant增强过程中使用的个别原生类方法进行增强可能会出现类循环依赖错误,目前已知不支持增强的原生类和方法如下所示: + +|类全限定名|类方法名| +| --- | --- | +|java.net.URL|构造方法| +|java.lang.ClassLoader|loadClass| \ No newline at end of file