响应式布局模板网站免费下载,做网站公司东莞,初级程序员与网站开发,视频制作表情包一、引言 组内最近做了一个日志公共组件#xff0c;用的是javaagent的方式#xff0c;之前搞的maven jar包每次都要把所有系统都发一遍#xff0c;太麻烦。 javaagent通过Java虚拟机#xff08;JVM#xff09;的Instrumentation API来实现代码的侵入。通过Instrumentation…一、引言 组内最近做了一个日志公共组件用的是javaagent的方式之前搞的maven jar包每次都要把所有系统都发一遍太麻烦。 javaagent通过Java虚拟机JVM的Instrumentation API来实现代码的侵入。通过Instrumentation APIJava agent可以在类加载过程中修改字节码向目标代码中插入自定义的逻辑或进行其他操作。我们的组件使用bytebuddy进行字节码修改。 今天发布系统会在流水线把这个日志组件带进去然后就出现了SoaServiceLogAction java.lang.NoClassDefFoundError: Could not initialize class **.LogConfig。
二、分析
1、原因 这个报错是很模糊的根本不知道具体原因正常有以下几种原因
1. 缺少依赖如果类 **.LogConfig 依赖于其他类或库而这些依赖没有正确地被引入到项目中就会导致找不到类的定义。 2. 类初始化失败如果类的静态初始化块或静态字段初始化过程中发生异常就会导致类初始化失败。这可能是因为初始化过程中的代码抛出了异常或者依赖的资源无法访问或加载。 3. 类路径冲突如果类 **.LogConfig在多个地方存在可能会导致类路径冲突从而无法正确加载类的定义。
2、组件 还是要看下代码这里只列出了出问题的地方省略了排查其他代码的过程。
public class LogConfig {
private static MapString, String config Config.get(**.properties).asMap();
public static String scenario() {return config.get(LOG_SCENARIO);}
} 这个没有类没有被正确初始化才导致了NoClassDefFoundError这个类在什么时候被调用呢
3、JavaAgent
Advice.OnMethodExit(suppress Throwable.class, onThrowable Throwable.class)public static void OnMethodExit(Advice.AllArguments(readOnly false, typing Assigner.Typing.DYNAMIC) Object[] allArguments,Advice.Thrown Throwable throwable) {try {if (StringUtils.isBlank(LogConfig.scenario())) {return;}//日志处理} catch (Throwable e) {e.printStackTrace();}} Advice.OnMethodExit 是bytebuddy库中的一个注解用于在方法退出时进行拦截和处理。它可以被用于在方法执行完毕后执行一些特定的逻辑例如记录日志、统计方法执行时间等。 这里可以看到判断一下对应的场景有没有配置使用日志组件。场景很多有数据库、链路调用、mq等等方便针对性的记录日志。
4、初始化分析 LogConfig在每次调用或者操作DB的时候都会被调用其中的静态方法scenario这时候就应该被初始化说明这个方法有问题。因为静态方法属于类级别的方法调用静态方法会导致类的初始化。在初始化过程中会执行静态初始化块和静态字段的初始化操作。因此在调用 scenario() 方法之前类 LogConfig 的静态字段 config 会被初始化。 那么会有什么问题呢config字段也就是加载一下配置而已。如果配置不存在呢作者想到这里看了一下配置中心果然没有这个文件。
三、解决 作者联系了系统对应的负责人加上**.properties这个文件但是感觉组件应该在本地建一个文件如果加载不到配置中心的也能加载到本地的。不然推广到其他部门的时候就会产生这种乌龙。
四、总结 java agent做公共代码的抽离是个好方式但是就像作者上次Log4j-tag丢失-CSDN博客发现的问题一样不看组件源代码根本不知道发生了什么。也就要求研发人员对JavaAgent有一定的了解。 下一期作者准备讲讲搭建和使用JavaAgent有兴趣的同学点点关注。